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