kotlin属性初始化和懒加载之lateinit、by lazy

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()
        }
    }

}

你可能感兴趣的:(kotlin属性初始化和懒加载之lateinit、by lazy)