首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Kotlin核心编程:Kotlin,改良的 Java

编者按:本文节选自华章科技出版的 《Kotlin核心编程》一书中的部分章节。

2010年,JetBrains产生创造Kotlin的想法。关于大名鼎鼎的JetBrains,想必在业内是人尽皆知,知名的IntelliJ IDEA就是他们的产品之一。拥有为各种语言构建开发工具经验的JetBrains,自然是对编程语言设计领域最熟悉的一群人。当时,一方面他们看到了C#在.NET平台上大放异彩;另一方面,Java相比新语言在某种程度上的滞后,让他们意识到改良Java这门主流语言的必要性。

JetBrains团队设计Kotlin所要面临的第一个问题,就是必须兼容他们所拥有的数百万行Java代码库,这也代表了Kotlin基于整个Java社区所承载的使命之一,即需要与现有的Java代码完全兼容。这个背景也决定了Kotlin的核心目标——为Java程序员提供一门更好的编程语言。

Kotlin的实用主义

Kotlin常常被认为是一门近似于Scala的语言。的确,它们的诞生都源于对Java语言的改良,同时都在面向对象和函数式之间建立起了多范式的桥梁。不可否认的是,Kotlin确实从Scala身上借鉴了许多,就连它的创作团队也表示过:“如果你用Scala感到很开心,那么你并不需要Kotlin。”

然而,Kotlin与Scala的设计哲学又十分不同。Kotlin并没有像Scala那样热衷于编程语言本身的研究和探索。相反,它在解放Java的同时,又在语言特性的选择上表现得相当克制。

我们说过,Scala旨在成为一门程序员梦想中的语言,它包含了所有你想拥有的语言特性。而Kotlin更加立足现实,它现阶段仍没有宏,也拒绝了很多所谓的高级函数式语言特性。但它在Java 的基础上发展出很多改善生产力的语言特性,如数据类、when表达式(一定程度上的模式匹配)、扩展函数(和属性)、可空类型等,而且它似乎偏好语法糖,比如Smart Casts,因为这可以让编程人员的工程开发变得更加容易。

可以看出,Kotlin的自我定位非常清晰,它的目标就是在计算机应用领域成为一门实用且高效的编程语言。如果说Scala的设计理念是more than Java(不仅仅是Java),那么Kotlin才是一门真正意义上的better Java(更好的Java)。

更好的Java

如果你用Kotlin开发过业务,很快就会意识到它相较于Java的语法更加简洁、高效。比如Kotlin做了这些改良:

  • 在很大程度上实现了类型推导,而Java在SE 10才支持了局部变量的推导。
  • 放弃了static关键字,但又引入了object,可以直接用它来声明一个单例。而作为比较,Java则必须依靠构建所谓的“单例模式”才能等效表达。
  • 引入了一些在Java中没有的“特殊类”,比如Data Classes(数据类)、Sealed Classes(密封类),我们可以构建更深程度上的代数数据类型,结合when表达式来使用。

但可能你会问,以上Kotlin的特性,Scala也有,能否可以说前者只是后者的一个子集呢?这种表述其实是不恰当的。其实,Kotlin在致力于成为更好的Java的道路上,不仅仅依靠这些新增的语言特性,它在兼容Java方面做了大量的工作,比Scala走得更远。

首先,从语言命名上就可以看出Kotlin在严格遵循Java的传统,它们都采用了岛屿的名字。

Java的名字来源于印度尼西亚瓜哇岛的英文名称,而Kotlin是俄罗斯圣彼得堡附近的一个岛屿的名字。

其次,虽然都是兼容Java,Scala(最近的几个版本)必须要求Java 8,而Kotlin则可以与Java 6一起工作,这也是后者在Android上更加流行的原因之一。

另外,Kotlin并没有像Scala那样在语法的探索上表现得“随心所欲”,Java程序员在学习Kotlin新语法特性的同时,依旧可以保留更多原有的习惯。举个例子,在Scala中,一切皆有类型。所以在大部分时间里,我们都用等号来定义一个Scala的函数。函数体最后一个表达式的值就是这个函数的返回类型。

def foo(x: Int) = {
    val y = x + 2
    x + y
}

没错,Scala舍弃了return关键字。在Kotlin中,它也引入了使用单行表达式来定义函数的语法,不需要用return来返回结果值。

fun foo(x: Int) = x * 2 + 2

然而,大部分情况下,我们还是可以采用类似Java的方式来定义一个函数,如:

fun foo(x: Int): Int {
    val y = x * 2
    return y + 2
}

由于Kotlin比Scala更加兼容Java的生态和语法,Java程序员可以更加容易地掌握它。同时,Kotlin非常注重语法的简洁表达。如果你了解Scala中的implicit,可能曾被这个Scala的语法惊吓到,因为它非常强大。然而,正如我们提到的,“简单灵活”的另一面意味着抽象和晦涩。Kotlin注重的是工程的实用性,所以它创造了扩展的语法,虽然相比implicit在功能上有损失,但显得更加具体直观,且依旧非常强大,可满足日常开发中绝大多数的需求。值得一提的是,Android则依靠这个Java所没有的特性,推出了扩展库android-ktx,我们在第7章将专门介绍这种强大的特性。

此外,Kotlin还新增了一些Java、Scala中没有的语法糖。如果你从事Android开发,那么肯定少不了在工程中写过如下的Java代码:

if(parentView instanceof ViewGroup){
    ((ViewGroup) parentView).addView(childView);
}

为了类型安全,我们不得不写两遍ViewGroup。然而在Kotlin中我们却可以直接这么写:

if(parentView is ViewGroup){
    parentView.addView(childView)
}

这依靠的是Kotlin中的Smart Casts特性。我们不评价这种语法糖是好是坏,但它可以在一定程度上改善我们在工程开发中的体验。

总体而言,Kotlin旨在成为一门提升Java生产力的更好的编程语言,它拥有简洁的表达能力、强大的工具支持,同时至今仍然保持着非常快速的编译能力。相较而言,用Scala开发则常常受到编译过慢带来的困扰。

强大的生态

现在,我们已经了解了Kotlin整体的设计哲学,以及它相较Java、Scala的魅力所在。当然,本章似乎并没有涉及任何语法细节,我们会在后续的内容中深入介绍Kotlin的语言特性,并且探索它具体的高级应用。

关于Kotlin,还有一个问题需要解答:我们究竟可以用它来做什么?大概率上你是因为Kotlin成为Android官方支持语言的新闻而知晓它的。事实上,Kotlin不仅支持Android,它还是一门通用语言,如果用一句话来总结,那就是“Targeting JVM / JavaScript and Native”。现阶段,我们至少可以用Kotlin做以下的事情。

(1)Android开发

我们不仅可以用Kotlin调用现成的Java库,而且还有Google提供的Kotlin扩展库。Kotlin的语法非常适合Android工程开发,例如我们提到过的Smart Casts。用它还可以改善findViewById的语法调用。

(2)服务端开发

这是JVM语言最大的一个应用领域,自然也是Kotlin发挥的舞台。在Android支持Kotlin之后,Spring Framework 5也对它敞开了怀抱。基于Kotlin更自然的函数式特性,用Spring进行Web开发会在某些方面拥有比Java更好的开发体验。

(3)前端开发

Kotlin还有两个强大的特性:dynamic类型及类型安全的构建器。前者实现其与JavaScript互通,后者可以帮助开发者构建可靠的HTML页面。你可以尝试使用Kotlin来构建UI。

(4)原生环境开发

因为Kotlin Native这个项目,Kotlin终于告别了Java,离开了JVM,直接编译成机器码供系统环境运行。虽然Kotlin Native尚处于早期阶段,但后续的发展非常值得期待。如果你家里有一个树莓派,不妨可以用它来试一试。

如你所见,Kotlin还是一门非常开放、具有强大生态的编程语言。如果说与Java兼容能让它运行在所有支持Java的地方,那么它的革命创新使得它超越了Java,进入了更加广阔的世界。

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/e6Q5tQ3DJoN8Vvc5BL7H
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券