Kotlin之constructor

kotlin constructor 知识点包括:

  • primary constructor
  • secondary constructor
  • init{…}

primary constructor:

class Person constructor(val name: String)

如果没有注解,或需要更改可见属性,可以忽略constructor关键字,所以上面的代码等价于:

class Person(val name: String)

我们查看对应的字节码包含:

  • 成员变量 private final String name
  • 成员属性 public final String getName()
  • 构造函数 public init(String name)
public final class com/example/myrxprogram/kotlin/Person {


  // access flags 0x12
  private final Ljava/lang/String; name
  @Lorg/jetbrains/annotations/NotNull;() // invisible

  // access flags 0x11
  public final getName()Ljava/lang/String;
  @Lorg/jetbrains/annotations/NotNull;() // invisible
  ......

  // access flags 0x1
  public <init>(Ljava/lang/String;)V
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
   ......
}

当需要使用注解,或更改可见性时,则需要显示使用constructor关键字

class Person @Inject constructor(val name: String)

class Person private constructor(val name: String)

secondary constructor:

关键字放在类内部

class Person {
    constructor(name: String) 
}

查看字节码生成,只有构造函数 public init(String name),不会生成成员变量和属性方法

public final class com/example/myrxprogram/kotlin/Person {


  // access flags 0x1
  public <init>(Ljava/lang/String;)V
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
   ......
}
secondary constructor需要和primary constructor组合使用:

class Person6(val name: String) {
    constructor(name: String, parent: String) : this(name) 
}

查看字节码,生成2个参数不同的构造函数init,也就是说secondary constructor实现了构造函数的重载

public final class com/example/guangda/myrxprogram/kotlin/Person6 {


  // access flags 0x12
  private final Ljava/lang/String; name
  @Lorg/jetbrains/annotations/NotNull;() // invisible

  // access flags 0x11
  public final getName()Ljava/lang/String;
  ......

  // access flags 0x1
  public <init>(Ljava/lang/String;)V
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
   ......

  // access flags 0x1
  public <init>(Ljava/lang/String;Ljava/lang/String;)V
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1
   ......
}

init{…}:类初始化代码块

class Person(val name: String){
    init{
        println("init person")
    }
}

我们查看字节码,init{……}部分和primary constructor部分被一起合并到构造函数init()中,见L2

public final class com/example/myrxprogram/kotlin/Person22 {

  ......

  // access flags 0x1
  public <init>(Ljava/lang/String;)V
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
   L0
    ALOAD 1
    LDC "name"
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V
   L1
    LINENUMBER 3 L1
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    ALOAD 0
    ALOAD 1
    PUTFIELD com/example/guangda/myrxprogram/kotlin/Person22.name : Ljava/lang/String;
   L2
    LINENUMBER 5 L2
    LDC "init person"
    ASTORE 2
   L3
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    ALOAD 2
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V
   L4
   L5
    RETURN
   L6
    LOCALVARIABLE this Lcom/example/guangda/myrxprogram/kotlin/Person22; L0 L6 0
    LOCALVARIABLE name Ljava/lang/String; L0 L6 1
    MAXSTACK = 2
    MAXLOCALS = 3

}

完整的示例:

class Person(val name: String){
    var parent=""

    constructor(name:String, parent:String):this(name){
        this.parent = parent
        println("secondary init person")
    }

    init{
        println("init person")
    }
}

总结:

本文主要讲解了kotlin的primary constructor ,secondary constructor ,init{}的定义,关系和如何使用。

    原文作者:Android
    原文地址: https://www.jianshu.com/p/9b17f5127f0b
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞