栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

kotlin基础教程:<8>类的延时成员变量、初始化代码块和陷阱

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

kotlin基础教程:<8>类的延时成员变量、初始化代码块和陷阱

之前我们讲到了类,怎么创建类,实例化类,类构造函数拥有两种,一种是主要构造函数,另一种是次要构造函数,次构造函数为了方便管理都需要调用一下主构造函数;

那么这一期我们来讲成员变量的延时;我们用到的一个关键字叫lateinit,它是用来延时实例化一个成员变量的时间用的,一般会延时到使用时实例化,当然还有一种是饿汉式:by lazy的组合使用来实现自动化的延时成员变量的实例化时;而且对于kotlin来说不想Java的代码对顺序那么灵活,一旦代码位置错了,就可能出现空指针:

1、加载类时的执行顺序

当我们调用次构造函数使用类时,类里面的成员、构造函数和init代码块是怎样的一个执行顺序呢?

我们知道,执行次构造函数必然需要调用主构造函数,而主构造函数有需要将成员全都初始化好,所以会先执行一气呵成的参数,就是带有val等参数类型的参数,然后执行init和其他的参数初始化,注意参数和init之间的先后顺序看你先写哪一个就限制性,所以我们可以说这些成员参数的执行和init代码块是并行执行的:

 public Tony2(@NotNull String _name, int age, @NotNull String info) {
      Intrinsics.checkNotNullParameter(_name, "_name");
      Intrinsics.checkNotNullParameter(info, "info");
      super();
      this.age = age;
      this.info = info;
      this.name = _name;
      String var4 = "我是init代码块:" + _name;
      System.out.println(var4);
      this.age1 = this.age;
   }

从反编译的Java代码可以看到,这个类调用次构造初始化时限制性了主构造,然后在里面执行了一气呵成的参数age和info,再就是先写的init代码块,最后是最后写的age,最最后执行次构造函数;

 //3.1 设置类构造函数的默认值        Tony3()    //3.2 初始化代码块    Tony2("Tony",4,"在学习kotlin")    Tony3("",4,22)

2、延时初始化成员,有时候我们想要我们的成员变量只有当用到的时候进行初始化,这里就可以使用延时成员变量的操作,含有两种,一种手动的延时,一种是自动的延时,也叫作懒汉式初始化变量:

 //4.1 声明一个延时初始化的成员,不需要赋值
    lateinit var info: String
    //定义一个函数来对成员赋值
    fun getrequest(){
        info = "Tony"
    }
    //打印结果
    fun showresult(){
        //注意这个isInitialized函数只能用在手动的演示初始化里面
        if(::info.isInitialized){
            println("初始化成功:${info}")
        }else{
            println("未被初始化")
        }
    }

主要步骤就是先定义好一个成员变量,注意要是用lateinit关键字表示是延时变量,然后定义一个函数用来给成员赋值,最后是使用这个变量;

第二种自动延时初始化是使用了by lazy:

 //4.2 还可以是by lazy的方式来自动延时初始化
    val info2: String by  lazy {
        getrequest2()
    }
    fun getrequest2(): String{
        return "jerry"
    }
    fun showresult2(){
        println("自动延时初始化:${info2}")
    }

我们在lazy的括号里调用这个赋值函数即可:

    //3.4 自动懒加载(by lazy)和懒加载(手动)
    Tony3().getrequest()
    Tony3().showresult()
    //4.3 使用自动延时初始化,我们就不需要手动调用函数,我们用到时它自己会调用
    Tony3().showresult2()

3、类的陷阱

以为kotlin是严格按照代码生成顺序执行的,所以大家务必对顺序需要了解:

//5.1 在类加载里面的陷阱
    
    Tony4("Tony").getinfo()

有时候我们可能会写一个成员是一个函数的返回值,而这个函数的返回值又是一个成员变量的值,不过这个变量是在调用函数的成员变量之后,那么我们会拿到一个null值。因为在他没有实例化的时候调用了它:

class Tony4(_info: String){
    //5.2 试一试不按照顺序的效果
    fun getinfo(){
        println("你传入的字符串长度:"+info.length)
        println("乘法结果:${number}")
        println("取值结果:${info1}")
    }
    //结果我们拿到的info1是一个null,这是因为顺序,info在info1的后面生成
    var info1 = getmethods()
    val info = _info
    //所以当我们调用获取info的值的函数时,info还没有赋值,所以为null
    fun getmethods() = "我拿到了${info}"
    var number = 9
    init {
        number = number.times(9)
    }
}

总之,kotlin当中的代码时严格按照代码顺序来执行,所以我们需要格外注意;那么这一期就到这。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/995652.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号