Kotlin之constructor

作者: wenson123 | 来源:发表于2018-05-15 16:41 被阅读18次

    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{}的定义,关系和如何使用。

    相关文章

      网友评论

        本文标题:Kotlin之constructor

        本文链接:https://www.haomeiwen.com/subject/vfkydftx.html