前言

lateinit是许多刚进入学习kotlin常常会掉入的坑之一。很多人为了保证java原有的语法,在定义变量和对象的过程中,会使用如下的定义方式。

class Demo{private var value: Stringfun printValue(){println(value)}
}

这个时候,编译器就会提示错误

Error:(2, 5) Kotlin: Property must be initialized or be abstract

然后有很多小伙伴解决问题,会使用提示符快捷键按钮自动修复这个问题,结果发现在定义变量的位置多了一个lateinit关键字

private lateinit var value: String

编译器的问题就这样躲避过去了,可是运行的过程,还是发生了异常问题。

原理

lateinit修饰属性的时候,实际上就是表示,这个属性初始化的时机和方式,由开发者自己决定。而编译器在编译kotlin语言的过程中,会将lateinit修饰属性的所有调用位置都做一个非空的检查判断,然后抛出异常。
// 字节码等价代码

fun printValue() {val tempValue = this.valueif(tempValue == null) {throw UninitializedPropertyAccessException("lateinit property value has not been initialized")}println(tempValue)
}

你定义value属性的值确实为null,但由于给定value的类型为String类型,而kotlin当中String类型是不允许容纳null,kotlin为了保证“绝对的空安全性”,所以只能抛出异常。

对于 Kotlin 新手来说,应该抛开 Java 式的写法,牢记类属性的三种初始化方式:

  • 主构造函数内定义属性,使用传入的参数初始化属性;
  • 类体内定义属性,同时初始化;
  • 类体内定义属性,init 块里初始化。

其他的初始化方式,慎用。

拓展

既然说到lateinit,那可以提一下kotlin中另一个常用的lazy。lazy并不是kotlin中的关键字,而是一个顶层函数,点击lazy跳转,可以看到lazy内部实现是通过高阶函数的方式。
tip:这里提到的顶层函数 和 高阶函数 就不做拓展了,想要了解的可以通过资料自行了解。

val b by lazy{// ...
}// LazyJVM.kt
public actual fun <T> lazy(initializer: () -> T): Lazy<T> = SynchronizedLazyImpl(initializer)

先说一下lazy的作用,顾名思义是懒加载的意思。懒加载这个词,估计很多开发者都不会陌生,我第一次听到懒加载是在viewpage + fragment的使用当中,通过懒加载的方式来减少加载数据时产生的内存消耗。而kotlin中的lazy,则是当b这个这个属性第一次被使用的时候,就会去初始化b这个对象,lazy后面跟的时一个lambda表达式,最后一行作为返回对象赋值给b。

lazy 和 lateinit

  1. lateinit 表示对全局变量进行延迟初始化,这样就不用一开始的时候将他赋值为null了。
  2. lazy 表示当调用该属性时,会执行该lazy内部的getValue()函数,而getValue()方法又会调用到lazy函数传入的lambda表达式,这样表达式的代码就可以得到执行。

Kotlin 之 lateinit关键字 与lazy相关推荐

  1. 【对比Java学Kotlin】object 关键字

    两种用法 Kotlin 的 object 关键字有两种用法,一个是作为右值表达式的前缀,一个是作为类的前缀修饰符. object 表达式 object 表达式一般用于对现有类进行稍微修改.因为是临时使 ...

  2. Kotlin的lateinit

    文章目录 简介 注意点 Kotlin源码及生成Java对比 简介 lateinit是延迟初始化属性修饰符,只能修饰var,因为需要在构造方法外修饰它的值,而val属性会被编译成final修饰的字段属性 ...

  3. Kotlin中的委托

    Kotlin中新引入的语法--委托.委托是一种设计模式,它的基本理念是:操作对象自己不会去处理某段逻辑,而是会把工作委托给另外一个辅助对象去处理. 比如调用A类的methodA方法,其实背后是B类的m ...

  4. 2021工资翻倍指南:Android面经,历时一个半月,斩获3个大厂offer

    历时一个半月,斩获3个大厂offer(京东.新浪.滴滴),这里进行下简单的总结,希望能帮助到大家. 总体来说,面试一般都是基于你的简历来进行的,一般先考察你的基础,然后考察你知识体系的完备程度,接着会 ...

  5. 万字篇:2020Android面经,历时一个半月,斩获3个大厂offer(京东、新浪、滴滴)

    原文链接:https://juejin.cn/post/6905226221357891592#heading-14 作者:tinyvampirepudge 好文推荐:文章看完很有感触,希望大家能多多 ...

  6. 2021Android面经,历时一个半月,斩获3个大厂offer

    历时一个半月,斩获3个大厂offer(京东.新浪.滴滴),这里进行下简单的总结,希望能帮助到大家. 总体来说,面试一般都是基于你的简历来进行的,一般先考察你的基础,然后考察你知识体系的完备程度,接着会 ...

  7. 2020Android面经,历时一个半月,斩获3个大厂offer

    历时一个半月,斩获3个大厂offer(京东.新浪.滴滴),这里进行下简单的总结,希望能帮助到大家. 总体来说,面试一般都是基于你的简历来进行的,一般先考察你的基础,然后考察你知识体系的完备程度,接着会 ...

  8. 2020Android面经,历时一个半月,斩获3个大厂offer,移动端开发工程师面试题

    ①AMS是如何确认Application启动完成的?关键条件是什么(zygote返给AMS的pid:应用的ActivityThread#main方法中会向AMS上报Application的binder ...

  9. Android茫茫半年求职路,终于斩获三个大厂offer,我总结了24家大厂100份面试题

    synchronized中的类锁和对象锁互斥么? 讲下Java的双亲委派. 泛型. 反射. 注解. 由于篇幅有限,仅展示部分内容,所有的知识点 整理的详细内容都放在了我的[GitHub],有需要的朋友 ...

最新文章

  1. linux一键安装包
  2. 利用ASP.NET向服务器上传文件[转]
  3. 统一归档助企业撑起信息的保护伞
  4. vrrp路由协议实验
  5. MATLAB二维数组的创建与元素提取
  6. c语言中验证巴德哥赫猜想,哥赫巴德猜想具体内容是什么?
  7. 用C语言实现猜单词的小游戏
  8. 【数据分享】学生受欢迎程度评价数据集
  9. 使用w3m访问页面执行函数
  10. 免费远程桌面连接工具
  11. 不理解 Java Steam?一步步梳理其工作方式
  12. 下载各种版本的weblogic
  13. Firefox扩展IE Tab Plus内置功能导致浏览所有网页加载superfish.com脚本
  14. C语言基础练习100--008(输出国际象棋棋盘)
  15. 徐有高:为你详细解读我国40省市新能源汽车补贴政策(转载)
  16. Python爬虫【如何爬取内容(html)和解析内容】
  17. 数组——洛谷#P1427 小鱼的数字游戏(Python实现)
  18. 国内外遥感类核心期刊汇总
  19. 使用R语言ggplot2包绘制pathway富集分析气泡图(Bubble图):数据结构及代码
  20. 用Faiss实现一个人脸检索

热门文章

  1. offer?三方协议?两方协议?毁约?
  2. mate30pro 优化 开发者选项_mate30pro怎么打开开发者选项
  3. mysql 按拼音码查询,MySQL拼音首字母查询
  4. linux xdm 启动执行文件,Linux下配置XDM登录服务器
  5. 深入解读云场景下的网络抖动
  6. 庖丁解牛Transformer原理
  7. 计算机视觉之三维重建——深入浅出SFM系统与SLAM系统的核心算法
  8. MySQL常用SQL(含复杂SQL查询)
  9. ppt怎么制作抖音快手快闪效果的倒计时动画?
  10. RH358服务管理和自动化--配置网络接口