朱涛 · Kotlin 编程第一课
朱涛
Google 认证的 Kotlin、Android 开发者专家,博客“Kotlin Jetpack 实战”作者
6717 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 50 讲
朱涛 · Kotlin 编程第一课
15
15
1.0x
00:00/00:00
登录|注册

03 | Kotlin原理:编译器在幕后干了哪些“好事”?

你好,我是朱涛。
在前面两节课里,我们学了不少 Kotlin 的语法,其中有些语法是和 Java 类似的,比如数字类型、字符串;也有些语法是 Kotlin 所独有的,比如数据类、密封类。另外,我们还知道 Kotlin 和 Java 完全兼容,它们可以同时出现在一个代码工程当中,并且可以互相调用。
但是,这样就会引出一个问题:Java 是如何识别 Kotlin 的独有语法的呢?比如,Java 如何能够认识 Kotlin 里的“数据类”?
这就要从整个 Kotlin 的实现机制说起了。
所以,今天这节课,我会从 Kotlin 的编译流程出发,来带你探索这门语言的底层原理。在这个过程中,你会真正地理解,Kotlin 是如何在实现灵活、简洁的语法的同时,还做到了兼容 Java 语言的。并且你在日后的学习和工作中,也可以根据今天所学的内容,来快速理解 Kotlin 的其他新特性。

Kotlin 的编译流程

在介绍 Kotlin 的原理细节之前,我们先从宏观上看看它是如何运行在电脑上的,这其实就涉及到它的编译流程。
那么首先,你需要知道一件事情:你写出的 Kotlin 代码,电脑是无法直接理解的。即使是最简单的println("Hello world."),你将这行代码告诉电脑,它也是无法直接运行的。这是因为,Kotlin 的语法是基于人类语言设计的,电脑没有人的思维,它只能理解二进制的 0 和 1,不能理解 println 到底是什么东西。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Kotlin编译器的幕后“好事”:深入探索Kotlin编译器的工作原理,揭示了Kotlin代码经过编译后会变成Java字节码,实现了Kotlin和Java的兼容。文章介绍了两种研究Kotlin原理的思路,并通过具体操作步骤,帮助读者快速了解Kotlin的实现细节。通过分析Kotlin的Long类型和接口语法的局限性,揭示了Kotlin编译器在背后进行的翻译工作,将Kotlin代码翻译成Java能理解的格式。文章还总结了Kotlin编译器在幕后所做的“好事”,如类型推导、原始类型转换、字符串模板处理等,使得读者能够深入了解Kotlin编译器的工作原理,为进一步学习和研究Kotlin打下基础。整体而言,本文通过简洁清晰的语言和实际例子,让读者能够快速了解Kotlin编译器的工作原理,体现了文章的技术特点。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《朱涛 · Kotlin 编程第一课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(32)

  • 最新
  • 精选
  • Renext
    思考题: 转换成 java代码就一清二楚,两种方式的isAdult本质不是同一个东西: 1-通过自定义 getter 来实现的方式,isAdult其实是一个方法。外部每一次调用,都是拿最新的age进行计算,所以age的值有变动,isAdult()的结果是最新的。 2- val isAdult = age >= 18 这种方式,isAdault是一个final变量,只会在对象新建时,在构造方法中,根据age的值赋值一次。所以,之后age的值如果有变动,isAdault值是永远不变的。

    作者回复: 赞!

    2021-12-31
    3
    61
  • PoPlus
    思考题: 如果采用 val isAdult = age >= 18 这种写法,那么错误会表现在给某个 Person 对象的 age 属性二次赋值时,isAdult 属性仍会是一个旧的 Boolean 值。原因:从反编译出的 Java 代码可以看出,isAdult 属性会被转换成一个 final 修饰的 Java 属性且在构造方法里赋好值了,那么意味着即使 age 属性后期修改一万遍,isAdult 属性也只会是它原来的那个初始值。 而如果用 getter 的方式则不会有这个问题,因为 getter 方式会把 isAdult 属性转换成 getter 方法而不是 final 修饰的属性,每一次调用,isAdult 属性就会动态的根据 age 属性来判断返回值。

    作者回复: 赞!分析的很到位。

    2021-12-31
    12
  • 阶前听雨
    太赞了,看了很多书和博客,基本都在讲kotlin多好用。从根本上讲kotlin的还是这门课,很多以前懵懵懂懂的概念都豁然开朗,太赞了。

    作者回复: 你的鼓励就是我的动力。我们一起加油!

    2021-12-31
    10
  • 逢庆
    1. val isAdult get() = age >= 18 反编译后可以看到,会生成方法: public final boolean isAdult() { return this.age >= 18; } 2. val isAdult = age >= 18 反编译后,可以看到: 会定义一个isAdult属性: private final boolean isAdult; 并在构造函数里根据age来赋值: this.isAdult = this.age >= 18;

    作者回复: 没错。

    2021-12-31
    7
  • 3.141516
    kotlin 的一些语法特性在编译为字节码后会增多 class 数量,所以会增加字节码的大小。 想请教下老师,在 Android 中,Kotlin 还有哪些方面会增加包大小呢?谢谢

    作者回复: 其实,我们一般说Kotlin增大包体积,主要只两个方面: 1. Kotlin标准库+反射库+协程库 2. 字节码增加class数量

    2022-02-09
    5
  • 文茂权
    JVM 由于存在多种实现,依赖的是一套标准规范。尽管学习 Kotlin 不需要直接接触 JVM ,但参考 JVM 的设计规范对于我们学习 JVM 编程语言的设计是很有作用的。 这里附上 JVM 不同版本的设计规范文档:https://docs.oracle.com/javase/specs/index.html

    作者回复: 赞!感谢补充。

    2022-01-16
    5
  • droidYu
    Kotlin语言的简洁得益于Kotlin编译器的强大,之所以Java和Kotlin能完全兼容,是因为Java和Kotlin编译后的成果都是Java字节码。

    作者回复: 是的。

    2022-03-20
    4
  • 郑峰
    You can define custom accessors for a property. If you define a custom getter, it will be called every time you access the property (this way you can implement a computed property). If you define a custom setter, it will be called every time you assign a value to the property, except its initialization.

    作者回复: 嗯,是的。

    2022-01-15
    3
  • qinsi
    直觉上反编译都是有损的,不知道有没有遇到过反编译结果不对的例子?

    作者回复: 确实,字节码才是最接近本质的。反编译成Java之后确实会损失少量信息,但一般都不会有很大的偏差。

    2022-01-01
    2
    2
  • PoPlus
    关于 Kotlin 包装类型优化原始类型,我的实验结果和老师的结论有一点出入,不知道是不是编译器版本的原因。🌚 var a: Long = 1 // private static long a = 1L; val b: Long = 2 // private static final long b = 2L; var c: Long? = 3 // private static Long c = 3L; 未优化成原始类型 val d: Long? = 4 // private static final Long d = 4L; 未优化成原始类型

    作者回复: 嗯,这是有可能的,我用的最新版IntelliJ,Kotlin1.6版本。

    2021-12-31
    2
    2
收起评论
显示
设置
留言
32
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部