java属性的初始化
在说kotlin属性初始化之前我们先来看下java属性的初始化
//可以不设置初始值,默认为null
private Object object;
//可以不设置初始值,默认为null,类创建时就进行默认复制
private static Object sObject;
{
object = new Object();
System.out.println("对象代码块");
}
//静态代码块在类创建时就进行初始化
static {
//object须为动态的,
sObject = new Object();
System.out.println("静态代码块");
}
//构造函数,创建实例对象的时候
public UserBean() {
object = new Object();
System.out.println("构造函数");
}
大体分为成员变量初始化、静态成员初始化、代码块初始化、静态代码块初始化
执行顺序打印如下:
image.png
kotlin属性初始化
-
1.类体内定义属性,同时初始化
image.png
从上图可以看出,编译器直接报错了,属性必须要被初始化。那么我们手动给他赋值为null呢,再来看看:
image.png
结果编译器还是报错,提示null不能赋值为一个非空值,意思是name默认为非空。写到这里,突然想到?可以声明修饰一个可空的属性,于是就有了
image.png
编译通过,说明这种方式的初始化必须的给一个非null的默认值,或者通过?指定一个null的初始值,初始值为null时,下面使用的地方也一定要通过name?进行访问,示例如下:
init {
name?.length
}
- 2.主构造函数内定义属性,使用传入的参数初始化属性
class User constructor(var name: String) {
}
- 3.类体内定义属性,init 块里初始化
init {
name = "haha";
}
再来看下lateinit和by lazy的区别:
lateinit
lateinit延迟初始化,lateinit只能修饰var,不能修饰val,当我们使用lateinit时就是告诉编译器这个属性的初始化时机由开发者把控,当我们未给这个被lateinit修饰的变量任何初始化时,
image.png
原因就是编译器会把lateinit修饰的变量在这个类中所有方法遍历一遍,看有没有对它进行初始化,没初始化就会报错。因此lateinit修饰的变量一定是要进行初始化的
by lazy
by关键字在kotlin中表达的委托的概念,by lazy只是会在使用到的时候进行初始化(类似懒汉式的单例),使用代理的方式调用get/set方法,所以var 不能声明by lazy修饰的属性
class User private constructor() {
companion object{
val instance:User by lazy {
User()
}
}
}