对比!Kotlin 与 Java 变量初始化顺序的区别

2,268 阅读3分钟

独处是一个自我启迪的过程

最近一直在看《Thinking in Java》这本书,中文名叫《Java 编程思想》,很早之前翻过一些,但由于有些内容很难理解,加上中文的翻译的不准确,最终没有坚持下去。

半个多月前,想系统性的回顾和总结 Android 体系中涉及的知识点,所以我开始每天花 2-3 个小时阅读这本书。有趣的是,在 2017年我就已经抛弃 Java 使用 Kotlin 来开发 Android,所以在看这本书的时候,脑子中会不断对比 Java 和 Kotlin 的异同。

在看到《Thinking in Java》第四章中变量初始化的时候,发现了一个有意思的地方,就当是读书笔记,记录下来和大家分享一下,有理解不对的地方,请及时指出。

Java 变量初始化顺序

在一个类里,初始化的顺序是由变量在类内的定义顺序决定的。即使变量定义大量遍布于方法定义的中间,那些变量仍会在调用任何方法之前得到初始化——甚至在构建器调用之前。

书中解释的很清楚,在类的构造方法执行之前,变量会初始化完成。

执行上图的代码,和我们预期的一样会先输出 Student 再输出  Teacher

Kotlin 变量初始化顺序

上图是 Kotlin 的代码,由于在 Koltin 中主构造函数不能包含任何的代码。初始化的代码可以放到以 init 关键字作为前缀的初始化块(initializer blocks)中。

执行 Koltin 代码和 Java 一样先输出 Student 再输出  Teacher。我反编译成 Java 代码,和我们上面写的 Java 代码是一样的,student 对象会在声明时直接初始化完成。

init 方法

有趣的地方就在这个 init 方法上面,我们通过 Koltin 反编译的 Java 代码可以看到,init 的方法会在构造方法中执行。

如果我把 Kotlin 代码中的 init 和  student 的初始化的执行顺序调换一下还会先输出 Student 再输出  Teacher吗?

结果是先输出 Teacher 后输出 Student

看到这里,大概也很好解释,init 和变量的初始化的执行顺序与他们在类中写的顺序有关。

事实也是如此,但是有一个问题,在看 《Thinking in Java》时书中说,在类的构造方法执行之前,变量会初始化完成,我们的 student 变量是在声明时初始化的,在 Java 中它一定会优于构造方法的初始化,但 Koltin 中 init 是在构造方法中执行的,在调换顺序之后,这个说法就不成立了,那么  student 是在什么时候初始化的呢?于是我又反编译了调换顺序之后的代码。

我们可以看到,student 的初始化放在了构造方法中,同时位于我们  init 代码之后。

总结

1.位于  init 代码块之前的变量会在声明时初始化早于构造方法2.位于  init 代码块之后的变量会在移至构造方法中初始化3.特别一点,当 Kotlin 类的默认构造方法有参数时,所以的变量都会移至构造方法中初始化 无奖竞猜🌝

探索有趣的新事物  

Android、Kotlin、设计、产品、思考、游戏。

长按关注

如果觉得有意思,那就分享一下啦