Kotlin 的诞生:专访 JetBrains 的 Andrey Breslav

作者:Janice J. Heiss

了解 Kotlin 这种新出现的 JVM 静态类型语言。

2013 年 4 月发布

近年来一项重要的 Java 软件进展就是 Groovy、Jython 和 JRuby 以及最近的 Scala 等 JVM 替代语言的出现。新的静态类型语言 Kotlin 最近受到关注。该语言以俄罗斯圣彼得堡附近的一个岛屿命名,Kotlin 的 Andrey Breslav 和 Kotlin 团队位于此地。作为备受称赞的捷克软件开发公司 JetBrains(Java IDE IntelliJ IDEA 的制作者)的智慧结晶,Kotlin 被 Dr. Dobb's Journal 2012 年 1 月刊 评为月度最佳语言。

Kotlin 项目的主要目的是为开发人员创建一种通用语言,可作为一种安全、简洁、灵活、与 Java 100% 兼容的有用工具。编译器和 IntelliJ IDEA 插件都是开源的,遵循 Apache 2 许可,源代码可通过 GitHub 获取。

Google 软件工程师、Java 测试框架 TestNG 的创建者 Cedric Beust 2011 年 7 月在 Javalobby 中写道:由于语法上的创新、强大的 IDE、来自合并编译器和 IDEA 支持的 JetBrains 的商业支持,以及其具体化的泛型,Kotlin 的出现值得欢庆。

Kotlin 的语言设计人员主管 Andrey Breslav 的职业生涯始于 Borland,当时他从事 MDA 支持的语言实现工作。在大学任教几年之后,他于 2010 年加入 JetBrains 领导 Kotlin 项目,目前是 Java Community Process 的 JSR 335“Lambda 项目”专家组成员。他经常在 OSCON、JavaOne、Strange Loop 和 Devoxx 等会议上发表演讲。

我们就 Kotlin 项目的现状对他进行了采访。

Andrey Breslav
Andrey Breslav

Oracle 技术网:您曾经写道,Kotlin 的目标是“创建一种 与 Java 100% 兼容,但比 Java 更安全、更简洁、更灵活,且不会过于复杂的语言”。请给我们详细介绍一下。

Breslav:每种工具的诞生都是因为某个用例的推动。我们认为,对于一种新的编程语言,这个用例就是逐步迁移,新语言一点一点引入用“旧”语言编写的大型代码库中。具体到我们,我们花费大量精力确保混合的 Kotlin/Java 项目顺利进行。

例如,IntelliJ IDEA 是用 Java 写的,我们希望在此项目中使用 Kotlin。当然,我们不是要以另一种语言重新编写整个长达 10 年的代码库。最有可能的是,先用 Kotlin 编写测试,然后是新特性,再然后可能是一些现有的子系统,经过重构后将迁移到 Kotlin。

“Kotlin 依赖于 Java 库,但可以增强 Java 库的功能,主要是通过扩展,但有时使用编译器支持的技术(集合、数组、基元)。”

             — Andrey Breslav
            JetBrains

所有这些意味着 Kotlin 必须在现有 Java 生态系统中表现得非常好:使用 Java 库、提供 Java API 并与 Java 框架集成。其他一些新语言采用不同的方法,目标是放弃 JDK,构建自己更好的平台。虽然此方法涉及在 JVM 上运行且技术上与 Java 兼容,但在我刚才所描述的用例中行不通。

至于 Kotlin,我们的集合库就是一个很好的示例。Scala 的经验表明,有自己的集合库 — 总的来说很不错 — 可以带来明显优势,但在需要与 Java 代码互操作时也存在缺点:所有数据都需要转换/包装,因此代码有点难看,性能有时会大打折扣。鉴于此,Kotlin 采用了另一种策略:我们使用简单的 Java 集合,但通过提取“虚拟”只读接口并引入声明位置变量使它们有不俗的表现。这样,既可兼顾兼容性,又可得到一个好用的库。

Kotlin 依赖于 Java 库,但可以增强 Java 库的功能,主要是通过扩展,但有时使用编译器支持的技术(集合、数组、基元)。这在保证兼容性的同时保持了语言的纯净。

Kotlin 和 Scala

Oracle 技术网:Kotlin 在哪些方面比 Scala 更简单?

Breslav:这要看怎么定义更简单。Kotlin 和 Scala 的方法大相径庭:Scala 的目标是为库设计人员提供尽可能强大的能力,它在很大程度上依赖于相当复杂的类型系统,而 Kotlin 的目标是为最终用户提供一个好用的工具,因此我们花了许多精力精简特性。

以下是 Scala 有而 Kotlin 没有的几项特性:

  • 隐式参数和隐式转换
  • (路径)依赖类型
  • 全面的实存类型
  • 视图边界、上下文边界以及所有其他特别的边界

此列表只不过是冰山一角。

“Kotlin 提供了比 Java(包括 Java 8)更灵活的抽象。”

             — Andrey Breslav
            JetBrains

Oracle 技术网:Kotlin 在哪些方面比 Java 更简洁?

Breslav:不太重要的部分是 Kotlin 一般不太拘泥于形式。以下是几个例子:

  • 类型推断更强,因此不必一再重复指定相同的类型。
  • 类声明更简洁,这要归功于属性和主构造器的概念。
  • 大部分时间不需要委托重载,这要归功于函数参数的默认值。
  • 由于有顶级函数,因此不需要静态实用程序类。

更重要的是,Kotlin 提供了比 Java(包括 Java 8)更灵活的抽象。下面是一些例子:

  • Kotlin 中的扩展函数和属性可以添加到任何类/类型,而不必修改该类的定义(相对于 Java 8 通过更改代码为接口添加方法的功能)。这样我们甚至可以改进现有 Java 库,使好的旧 JDK 也显得精致、炫亮。
  • 更高级的函数(以值的形式传递代码)要方便得多,因为 Kotlin 支持适当的函数类型(相对于 Java 8 的 SAM 转换,每次需要传递新的函数签名时创建一个新的接口)。
  • 声明位置变量,尤其是变体集合,通过消除泛型中对无处不在的通配符的需要,使常用数据处理更自然。

Oracle 技术网:您收到的有关 Kotlin 的最负面的反馈是什么?

Breslav:“它还没有发布。”

Oracle 技术网:最正面的呢?

Breslav:“一种语言最终解决所有问题!”

Kotlin 的发布状态

Oracle 技术网:Kotlin 的发布状态如何?开发人员如何参与?

Breslav:2013 年 2 月初,Kotlin 到达 M5 里程碑。至于大的特性,我们主要是稳定它们并努力提高性能。还新增了一些较小的特性。该项目欢迎参与,我们将尽快合理地处理提交的问题或申请。

对于 1.0 版本的发布,尚无无明确时间表。这是我们理念的一个重要部分。当针对 1.0 计划的特性稳定且编译器达到发布质量时,我们不会称其为 1.0。而将是 beta 版,可供任何人使用,但不保证更新的向后兼容性。关键是在“beta”阶段,语言最终将用于生产环境(其他公司可能一开始会避免这么做,但至少 JetBrains 将明确使用 Kotlin),大量的生产应用可以暴露语言设计中一些需要修复的问题。

不要误解:我们正在尽全力将该语言打造得完美无缺。我们依赖我们最好的工程师的经验,以及我们不断从其他公司和个人收集的反馈。但我们知道,在实践中总会遇到理论所没注意到的种种意外,因此我们非常欢迎任何在发布之前承诺不对其进行改动的前提下验证设计的需求。这就是为什么我们没有 1.0 的时间表,且并不保证 beta 版刚推出时语言设计稳定性的原因:难以预测需要做出哪些改懂。

对设计进行了适当的验证并修复了所有问题后,我们将称其为 1.0 并保证之后的语言稳定性。

Oracle 技术网:JetBrains 目前在 IntelliJ IDEA 的生产和其他项目中使用 Kotlin。请谈谈在 IntelliJ IDEA 中使用 Kotlin 的情况。遇到了哪些挑战?

Breslav:首先,现在只有那些非常勇敢的人才将 Kotlin 用于生产。其中最勇敢的使用尚未成熟的 JavaScript 后端对 Kotlin 进行编译以便在浏览器中运行。这些是非常艰巨的挑战,但结果是惊人的:IntelliJ IDEA 的 Live Edit

增强 Java 库

Oracle 技术网:请给我们举几个例子说明 Kotlin 可在哪些方面增强 Java 库。

Breslav:首先,是 Kotlin 处理集合的方式:它在运行时使用标准 JDK 类,但在编译时,它将引入协变的“虚拟”只读接口,因此可以在期望(只读)List<Object> 的位置传递(只读)List<String>

另外,Kotlin 还为集合类引入了许多扩展函数。例如,使用 map()filter() 函数可以流畅地操纵数据:

users.filter {u -> u.age >= 21}.map {u -> u.name}

通过扩展还做了许多其他事情:从 for 循环支持到操作符过载和类似字节组的操作。

其他替代语言

Oracle 技术网:在不断增加的 JVM 新语言中,Kotlin 的定位在哪里?它与 Groovy、Jython、JRub、Scala 及其他语言相比如何?有这么多语言可用,为什么还需要 Kotlin?

Breslav:Groovy、Jython 和 Ruby 主要是动态的,而 Kotlin 是静态类型的,这意味着它可以在编译时捕获更多错误(类型安全)、执行速度更快、工具更智能。

Groovy 2.0 的静态编译特性令生成的代码执行速度堪比 Java,这对 Groovy 是一个巨大的改进。但它支持的类型系统是 Java 所使用的,意味着所有抽象机制完全相同 — 例如,获得 Java 泛型的同时将连带使用位置变量等所有不便。

Scala 则是另一回事(它是静态类型语言),我们从 Scala 的设计学到了不少东西。与 Kotlin 相比,Scala 要强大得多,人和机器更难真正理解它。

Oracle 技术网:请谈谈 Kotlin 中的 IDE 支持。

Breslav:我们在启动编译器同时启动了一个适用于 Kotlin 的 IntelliJ IDEA 的插件,并在两者之间重用了许多代码。这一方面可以保证 IDE 中的分析非常准确,同时可以使用 IntelliJ IDEA 现有的针对 Java 的基础架构。

Oracle 技术网:Kotlin 哪些最重要的特性是 Java 所没有的?

Breslav:假设“Java”指的是 Java 8,且这十年最大的难题 lambdas(经常称为“闭包”)已经存在:最重要的特性是强大的类型推断、扩展、声明位置变量和集合的只读接口。

在库方面:类型安全的构建器也很重要。

做好使用 Kotlin 的准备

Oracle 技术网:开发人员如何做好使用 Kotlin 的准备?你们需要什么反馈?

Breslav:下载编译器和/或适用于 IntelliJ IDEA 的插件,编写您很酷的应用程序。我们需要的反馈是关于人们喜欢和不喜欢 Kotlin 的哪些方面,哪些是他们觉得难以理解的,以及他们如何使用该语言提供的特性。

Oracle 技术网:什么样的 Java 开发人员从 Kotlin 受益最大?

“我们需要的反馈是关于人们喜欢和不喜欢 Kotlin 的哪些方面,哪些是他们觉得难以理解的,以及他们如何使用该语言提供的特性。”

             — Andrey Breslav
            JetBrains

Breslav:达到语言极限的 Java 开发人员(相信我们中许多人在很久以前都遇到过)意识到需要一种新的语言,具有更干净的抽象、简介的语法、类型安全等优点。

Oracle 技术网:Kotlin 在哪些方面比 Java 更安全?Kotlin 解决了 Java 中的哪些安全问题?

Breslav:Kotlin 通过可为空的类型提升了空值安全性。它还通过只读集合和数据类提供了数据修改控制,并通过智能转换实现了更安全的运行时检查。

Oracle 技术网:Kotlin 修复了哪些 Java 使用问题?

Breslav:它修复了 Joshua Bloch 的 Java Puzzlers 丛书中提及的半数问题:从基元隐式转换的怪异行为,到静态成员及其继承的问题,直到正确的变体泛型和空值安全性。

Oracle 技术网:您遇到的关于 JVM 尤其是 Kotlin 语言的最大误解是什么?

Breslav:我们总是碰到函数式编程 这个术语,人们谈到这个词的时候往往指的是不同的东西,如果有的话。

ML 和 Haskell 等较大的函数式语言已形成了一些人高度赞赏的一定规范和美感,但这显然不是您附近隔间的同事在午餐时与您谈论函数式编程的原因。

“面向大众的函数式编程”的主要卖点在于其有助于解决现在每个人都很头疼的并发性问题,而且这种有用性的论据通常归结为“无副作用等同于没有问题”或“无共享内存等同于没有问题”。

按照这种推理,我们需要的只是不可变数据和/或隔离,但这并不一定产生函数式语言的任何美感或严谨性。函数式语言中广泛使用的其他东西非常适合在主流编程中采用 — 这主要适用于类型安全的抽象方式,如高级函数(以其他函数作为参数的函数)和参数多态性(泛型)。但这些特性同样没有定义函数式语言。

我的观点是:一个好的语言不需要是类似 Haskell 的函数式,尽管它需要一些“函数世界”流行的特性。

另请参见

关于作者

Janice J. Heiss 是 Oracle 的 Java 策划编辑,还是 Java Magazine 的技术编辑。

分享交流

请在 FacebookTwitterJava Source 博客上加入 Java 社区对话!