Kotlin 中初始化块初始化的顺序lateinit延迟初始化详解

Posted 路宇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin 中初始化块初始化的顺序lateinit延迟初始化详解相关的知识,希望对你有一定的参考价值。

前些天发现了一个蛮有意思的人工智能学习网站,8个字形容一下"通俗易懂,风趣幽默",感觉非常有意思,忍不住分享一下给大家。
👉点击跳转教程

1、初始化块:初始化块可以设置变量或值,以及执行有效性检查,如检查传给某构造函数的值是否有效,初始化块代码会在构造类实例时执行。

案例代码如下:

class Player3(
    _name: String, var age: Int = 20, var isNormal: Boolean
) 
    var name = _name
        get() = field.capitalize()
        set(value) 
            field = value.trim()
        

    //次构造函数
    //我们可以定义多个次构造函数来配置不同的参数组合
    constructor(name: String) : this(name, age = 100, isNormal = false)
    constructor(name: String, age: Int) : this(name, age = 10, isNormal = false) 
        println("次构造函数")
        this.name = name.toUpperCase()
    

    init 
        println("测试init")
        require(age > 0) 
            "age muse be positive"
        
        require(name.isNotBlank()) 
            "player must have a name"
        
    


fun main() 
    val player = Player3(isNormal = false, _name = "Jack")
    println("$player.name, $player.age, $player.isNormal")
    val p = Player3("android", 10)
    println("$p.name,$p.age,$p.isNormal")

输出结果如下:

测试init
Jack, 20, false
测试init
次构造函数
ANDROID,10,false

2.初始化执行的顺序

  1. 主构造函数里声明的属性
  2. 类级别的属性赋值
  3. init初始块里的属性赋值和函数调用
  4. 次构造函数里的属性赋值和函数调用

案例代码如下:

class Students(
    _name: String, val age: Int
) 
    var name = _name
    var score = 10
    private val hobby = "music"
    val subject: String

	//初始化块
    init 
        println("initializing Students...")
        subject = "math"
    

    constructor(_name: String) : this(_name, 10) 
        score = 20
    


fun main() 
    Students("Jack")

可以通过反编译看java代码,就清楚了,反编译代码如下

public final class StudentsKt 
   public static final void main() 
      new Students("Jack");
   

   // $FF: synthetic method
   public static void main(String[] var0) 
      main();
   

// Students.java
package kotlin04;

import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;

@Metadata(
   mv = 1, 6, 0,
   k = 1,
   d1 = "\\u0000\\u001a\\n\\u0002\\u0018\\u0002\\n\\u0002\\u0010\\u0000\\n\\u0000\\n\\u0002\\u0010\\u000e\\n\\u0002\\b\\u0002\\n\\u0002\\u0010\\b\\n\\u0002\\b\\u000f\\u0018\\u00002\\u00020\\u0001B\\u000f\\b\\u0016\\u0012\\u0006\\u0010\\u0002\\u001a\\u00020\\u0003¢\\u0006\\u0002\\u0010\\u0004B\\u0015\\u0012\\u0006\\u0010\\u0002\\u001a\\u00020\\u0003\\u0012\\u0006\\u0010\\u0005\\u001a\\u00020\\u0006¢\\u0006\\u0002\\u0010\\u0007R\\u0011\\u0010\\u0005\\u001a\\u00020\\u0006¢\\u0006\\b\\n\\u0000\\u001a\\u0004\\b\\b\\u0010\\tR\\u000e\\u0010\\n\\u001a\\u00020\\u0003X\\u0082\\u0006\\u0002\\n\\u0000R\\u001a\\u0010\\u000b\\u001a\\u00020\\u0003X\\u0086\\u000e¢\\u0006\\u000e\\n\\u0000\\u001a\\u0004\\b\\f\\u0010\\r\\"\\u0004\\b\\u000e\\u0010\\u0004R\\u001a\\u0010\\u000f\\u001a\\u00020\\u0006X\\u0086\\u000e¢\\u0006\\u000e\\n\\u0000\\u001a\\u0004\\b\\u0010\\u0010\\t\\"\\u0004\\b\\u0011\\u0010\\u0012R\\u0011\\u0010\\u0013\\u001a\\u00020\\u0003¢\\u0006\\b\\n\\u0000\\u001a\\u0004\\b\\u0014\\u0010\\r¨\\u0006\\u0015",
   d2 = "Lkotlin04/Students;", "", "_name", "", "(Ljava/lang/String;)V", "age", "", "(Ljava/lang/String;I)V", "getAge", "()I", "hobby", "name", "getName", "()Ljava/lang/String;", "setName", "score", "getScore", "setScore", "(I)V", "subject", "getSubject", "kotlinStudy"
)
public final class Students 
   @NotNull
   private String name;
   private int score;
   private final String hobby;
   @NotNull
   private final String subject;
   private final int age;

   @NotNull
   public final String getName() 
      return this.name;
   

   public final void setName(@NotNull String var1) 
      Intrinsics.checkNotNullParameter(var1, "<set-?>");
      this.name = var1;
   

   public final int getScore() 
      return this.score;
   

   public final void setScore(int var1) 
      this.score = var1;
   

   @NotNull
   public final String getSubject() 
      return this.subject;
   

   public final int getAge() 
      return this.age;
   

   public Students(@NotNull String _name, int age) 
      Intrinsics.checkNotNullParameter(_name, "_name");
      super();
      this.age = age;
      this.name = _name;
      this.score = 10;
      this.hobby = "music";
      String var3 = "initializing Students...";
      System.out.println(var3);
      this.subject = "math";
   

   public Students(@NotNull String _name) 
      Intrinsics.checkNotNullParameter(_name, "_name");
      this(_name, 10);
      this.score = 20;
   

3、延迟初始化lateinit

class Player4 
    lateinit var equipment: String

    fun ready() 
        equipment = "sharp knife"
    

    fun battle() 
        if (::equipment.isInitialized) //该属性初始化,执行该代码
            println(equipment)
        
    


fun main() 
    val p = Player4()
    p.ready()
    p.battle()

输出结果

sharp knife

以上是关于Kotlin 中初始化块初始化的顺序lateinit延迟初始化详解的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin类的初始化 ③ ( init 初始化块 | 初始化顺序 : 主构造函数属性赋值 -> 类属性赋值 -> init 初始化块代码 -> 次构造函数代码 )

Kotlin类的初始化 ③ ( init 初始化块 | 初始化顺序 : 主构造函数属性赋值 -> 类属性赋值 -> init 初始化块代码 -> 次构造函数代码 )

Kotlin 主构造函数 次构造函数 默认参数 init代码块 初始化顺序

Kotlin之初始化

Kotlin 初始化陷阱。初始化注意事项

Kotlin 常用语法篇