从 Java 到 Scala,再到 Kotlin

在 Java 以后,JVM 平台上出现了一些其余的编程语言,Scala 和 Kotlin 能够算是其中的佼佼者。Scala 已成为大数据领域的明星,Kotlin 在 2017 年 Google IO 大会以后,俨然也成为了安卓平台潜力巨大的官方支持语言。他们都被冠以“更好的Java”而称道,然而它们采用的是两种不一样的设计理念。前端

本文咱们会经过对比 Java、Scala、Kotlin 这三门语言各自的发展路线,来认识 Kotlin 的设计哲学。java

Java的发展

不得不说,Java是当今最成功的编程语言之一。自1996年Java问世,它始终霸占着编程语言生态中很大的一块。它的优点主要体如今:android

  • 多平台与强大的社区支持。不管是在Web开发仍是移动设备,Java都是最主流的编程语言之一;
  • 尊重标准,有着严格的语言规范以及向后兼容性。所以Java很是适合开发团队之间的协做,即便组织变更,新人一样能够在相同的规范下快速推动项目。

然而,随着计算平台的快速发展,平台和业务自己对编程语言提出了更大的挑战。Java的发展也受到环境变化所带来的影响。如多核时代与大数据的到来,使得古老的函数式编程又从新变得“时髦”,Scala、Clojure这种多范式的编程语言开始受到愈来愈多开发人员的关注和喜好。另外一方面,Java的严格规范也经常被吐槽乏味。程序员

所以,Java必须开始改变。编程

Java 8的探索

若是说Java 5引入泛型是Java发展历史上重大的进步,那么Java 8的发布也一样意义深远,它是Java对其将来发展一次崭新的探索。Java 8引入了不少全新的语言特性,如:设计模式

  • 高阶函数和Lambda。首次突破了只有类做为头等公民的设计,支持将函数做为参数来进行传递,同时结合Lambda语法,改变了现有的程序设计模式;
  • Stream API。流的引入简化了平常开发中的集合操做,并赋予了更强大的业务表达能力,并加强了代码的可读性;
  • Optional类。为消除null引用所带来的NullPointerException问题在类型层面提供了一种解决思路。 这一次的发布在Java社区引来了不一样寻常的反响,由于Java程序员开始感觉到另一种编程范式所带来的全新体验—也就是所谓的函数式编程。拥抱函数式也为Java的发展指引了一个很好的方向。

Java将来会是什么样子

2016年11月在欧洲最大的Java峰会上,Oracle的Java语言架构师—Brian Goetz分享了关于Java这门语言将来发展的演讲。本次会议最大的收获,就是探索了将来Java可能支持的语言特性,它们包含了:安全

  • 数据类
  • 值类
  • 泛型特化
  • 更强大的类型推导
  • 模式匹配

以上的语言特性,对于初尝函数式编程甜头的Java开发者而言,是十分值得期待的。它们能够进一步解放Java,让开发工做变得更加高效和灵活。好比,一旦Java支持了数据类,咱们就能够用很是简短的语法来表示一个常见的数据对象类,就像这样子:架构

public class User(String firstName, String lastName, DateTime birthday) 复制代码

而用现在的JavaBean,则意味着好几倍的代码量,这一切都让人火烧眉毛。与此同时,或许早有Java程序员开始了JVM平台上另外一种语言的研究。这门语言已支持了全部这些新的特性,并在设计的一开始,就集成了面向对象和函数式两大特征,它就是Scala。编程语言

Scala的百宝箱

Scala是洛桑联邦理工大学的马丁(Martin Odersky)教授创造的一门语言。他也参与了Java语言发展的研究工做,Java 5引入泛型就是他的杰做。事实上,在Java刚发布的时候,马丁教授就开始了Java的改良工做—他在JVM平台探索函数式编程,发布了一个名为Pizza的语言,那时就支持了泛型、高阶函数和模式匹配。函数式编程

然而,在随后的探索过程当中,他渐渐发现Java是一门具备硬性约束的语言,在某些时候不能采用最优的方式来实施设计方案。所以,他和他的研究伙伴决定从新创造一门语言,既在学术上合理,同时也具有实用价值,这就是Scala的由来。

学术和工业的平衡

Scala是一门很是强大的编程语言,正如它名字(Scalable—可拓展)自己,用Scala编程就像拥有了哆啦A梦的口袋,里面装满了各类编程语言特性,如面向对象、函数式、宏。

Scala不只在面向对象方面进行了诸多的改良,并且完全拥抱了函数式。所以Scala也吸引了函数式编程社区不少厉害的程序员,他们将函数式编程的思想注入到了Scala社区,如此将使用Scala进行函数式编程提升到了新的高度。

因为Scala设计者学院派的背景,以及它某些看似“不一样寻常”的语法,它在发展早期(甚至如今)常常被描述为“过于学院派”,以致于马丁教授在某次Scala大会的演讲时,自嘲“Scala真正的做用是将人引向了Haskell”。

然而,真实的Scala倒是在不断地探索学术和实用价值两方面的平衡。不能否认的是:

  • Scala已经成为大数据领域的热门语言,明星项目Spark就是用Scala开发,还有不少其余知名的项目如Akka、Kafka;
  • 愈来愈多的商业公司如Twitter、PayPal、Salesforce都在大量使用这门语言。

另外一方面,Scala也确实是一门有着较陡的学习曲线的语言,由于它强大且灵活,正如马丁教授本身所言,Scala相信程序员的聪明才智,开发人员能够用它来灵活选择语言特性。但学术和工业的平衡始终是一个难题,与Java严格标准相比,Scala的多重选择也经常让人吐槽它复杂。

复合但不复杂

那么,Scala真的复杂吗?咱们不知听了多少次相似这样的抱怨。在搞明白这个问题以前,咱们须要先弄清楚到底什么是“复杂”。在英文中,复杂一词能够联想到两个单词—complex和complicated。实际上它们的含义大相径庭,更准确地说,complex更好的翻译是“具备复合性”。 Nicolas Perony曾在Ted上发表过一次关于“复合性理论”的演讲。

什么是复合性?复合并非复杂。一件复杂的事物是由不少小部分所组成的,每一部分都各不相同,并且每一部分都在这个体系中有其自身的确切做用。与之相反,一个复合的系统,由不少相似的部分所组成,并且(就是由于)它们之间的相互影响,才造成了一种宏观上一致的行为。复合系统含有不少相互动的元素,它们根据简单的、个体的规则行动,如此致使新特征的出现。

马丁教授一样发表过一篇名为《简单仍是复杂》的文章,表达过相似的观点。若是对搭积木这件事情进行思考,摩比世界提供固定的方案,而乐高提供了无穷的选择。然而,前者的零件种类数量比后者要多得的。相似的道理,编程语言能够依靠功能累加来构建所谓的语法,一样也能够经过简单完备的理论来发展语言特性,在马丁教授看来,Scala显然属于后者,它并不复杂,并且很是简单。

简单却不容易

事实上,函数式编程最明显的特征就是具有复合性。函数式开发作的最多的事情,就是对所须要处理的事物进行组合。若是说面向对象是概括法,侧重于对事物特征的提取及归纳;函数式中的组合思想则更像是演绎法,近似数学中的推导。

然而,“简单”的哲学也带来了相应的代价:

  • 这是一种更加抽象的编程范式,诸如高阶类型、Typeclass等高级的函数式特性虽然提供了无比强大的抽象能力,但学习成本更高;
  • 创建了另外一种与采用Java面向对象编程大相径庭的思惟模式。这种思惟方式上的巨大差别,显然是一个极高的门槛,同时也是形成Scala使人望而却步的缘由之一。

Scala在选择完全拥抱函数式的同时,也意味着它不是一门容易的语言,它没法成为一门像Java那样主流的编程语言。事实上,即便不少人采用Scala来进行开发,也仍是采用相似Java的思惟模式来编程,换句话说,Scala依旧是被当作是更好的Java来使用,但这确实是当今主流编程界最大的诉求。

在这种背景下,Kotlin做为一门JVM平台上新兴的编程语言,悄悄打开了一扇一样广阔的大门。

Kotlin—改良的Java

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

JetBrain团队设计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。

此外,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咱们至少能够用它作如下的事情:

  • Android开发

咱们不只能够用Kotlin调用现成的Java库,并且还有Google提供的Kotlin扩展库。Kotlin的语法很是适合Android工程开发,例如咱们提到过的Smart Casts,用它还能够改善findViewById的语法调用;

  • 服务端开发

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

  • 前端开发

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

  • 原生环境开发

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

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

小结

咱们打算用一个比喻来结尾。这个生动形象的说法来自于Lutz Hühnken的博客,他把Java、Scala、Kotlin比做滑雪运动中的不一样种类。

若是说JVM平台是一个滑雪世界,那么最先的Java语言就是你们最熟知的滑雪方式—双脚各踏一个滑雪板来进行滑雪。Scala则更像将两只脚都站在一块单板上来滑行的滑雪方式。那些用滑雪单板的高级运动员很是使人羡慕,由于他们能够用更优雅的姿式得到更快的速度,并且最重要的是他们能够作“深粉雪”滑行,这也就是所谓的函数式编程。

然而,对于用惯双板滑雪的运动员而言,尝试用单板来滑雪,就像是学习一种新的运动,会常常摔跤。其实,大部分人仍是更乐意用双板来进行滑雪。这时候,刻滑板出现了,使用它,运动员彻底能够保留原有双板的习惯,但同时依旧能够作某个程度上的深粉雪滑行。你猜的没错,它就是Kotlin。

对于滑雪这项运动而言,别忘了,还有一个世界性的赛事—Android开发,它暂时并无对单板开放,但对刻滑板则已经敞开了怀抱。

因此,若是你是想要寻找一种更好的Java语言的话,欢迎来到Kotlin的滑雪世界!

以上内容摘自《Kotlin核心编程》

相关文章
相关标签/搜索