Java 的新未來(lái):逐漸“Kotlin 化”
來(lái)自不同編程語(yǔ)言的競(jìng)爭(zhēng)正促使 Java 不斷吸收新特性,變得更能適應(yīng)時(shí)代和開(kāi)發(fā)人員的新需求。
我們行業(yè)始終有一個(gè)熱門(mén)話題,那就是對(duì) Java 的批判,這種批判很大程度上來(lái)源于 Java 的繁瑣性以及它所生成的大量樣板式代碼,而這些代碼在很多場(chǎng)景下是根本不需要的。
雖然我一直以來(lái)都很喜歡 Java,但是我不能說(shuō)這些指責(zé)是錯(cuò)誤的。的確,Java 的繁瑣性以及數(shù)量不菲的雜亂代碼在很多情況下會(huì)很煩人。在大多數(shù)情況下,我們不得不接受我們生活在一個(gè)不完美的世界這一現(xiàn)實(shí),很多時(shí)候,我們必須兩害相權(quán)取其輕。我們都知道,Java 并不完美,但是主要的問(wèn)題在于在此之前為什么沒(méi)有采取任何措施來(lái)解決這些問(wèn)題呢?
我認(rèn)為,變更需要耗費(fèi)這么長(zhǎng)時(shí)間的唯一原因就是 Java 缺乏足夠的競(jìng)爭(zhēng)。Java 語(yǔ)言之所以能夠主導(dǎo)市場(chǎng),可能就是因?yàn)槿狈φ嬲母?jìng)爭(zhēng)對(duì)手,當(dāng)然也要?dú)w功于 Sun 和 Oracle 先后做出的巨大努力。
Java 提供的強(qiáng)類型安全性,以及作為一個(gè)結(jié)構(gòu)良好的語(yǔ)言所帶來(lái)的其他特性,使其成為大型項(xiàng)目中非常流行的語(yǔ)言。通過(guò)使用 Java,我們很少會(huì)讓事情變得難以收拾。Java 的另外一個(gè)重要特點(diǎn)是作為多平臺(tái)語(yǔ)言,它運(yùn)行在自己的虛擬機(jī)上,這使其能夠完美契合很多的組織。如果你通過(guò)著名的 JIT 編譯器啟用了其自動(dòng)性能優(yōu)化的固有能力,那么在很多情況下都能將糟糕代碼所帶來(lái)的影響最小化,這樣我們就有了一組使用 Java 的堅(jiān)實(shí)理由。
但是,后來(lái)發(fā)生了什么呢?接下來(lái)的事情就是,能夠像 Java 那樣運(yùn)行在相同 JVM 中的新語(yǔ)言推向了市場(chǎng),這些語(yǔ)言消除了 Java 中最令人頭疼的問(wèn)題,并為開(kāi)發(fā)人員提供了更好的環(huán)境,而且在很多情況下,它們的學(xué)習(xí)曲線非常平坦。
在繼續(xù)下面的內(nèi)容之前,我們簡(jiǎn)要回顧一下 JVM 語(yǔ)言的歷史。
1. JVM 語(yǔ)言的歷史
在開(kāi)始之前,我想澄清一點(diǎn),那就是我省略掉了一些現(xiàn)有的 JVM 語(yǔ)言,這主要是因?yàn)樗鼈儚膩?lái)沒(méi)有具備足夠強(qiáng)的吸引力,不能視為我們行業(yè)中廣泛使用的候選語(yǔ)言。那么,我們就開(kāi)始快速回顧一下 JVM 語(yǔ)言的歷史。
圖片出自 Unsplash 站點(diǎn),作者為 Maximilian Weisbecker
我們的旅程當(dāng)然要從 Java 開(kāi)始,它是 JVM 領(lǐng)域最古老和最流行的語(yǔ)言。
Java 語(yǔ)言最初是在 1996 年 1 月份正式發(fā)布的,所以它已經(jīng)有 24 年的歷史了,怎么樣,還不錯(cuò)吧?最初,Java 是一種命令式語(yǔ)言,遵循純粹的面向?qū)ο蟪绦蝻L(fēng)格。它同時(shí)也是強(qiáng)類型語(yǔ)言,Java 的語(yǔ)法在某種程度上與 C++ 和 C 語(yǔ)言很相似,但它被認(rèn)為是一個(gè)改進(jìn)版本,因?yàn)槭褂?Java 編寫(xiě)代碼要比使用 C 或 C++ 容易得多。另外,在它的批評(píng)者中,最大的爭(zhēng)議在于其繁瑣性。
第二個(gè)發(fā)布的 JVM 語(yǔ)言是 Groovy,它最早出現(xiàn)于 2003 年,不過(guò)其第一個(gè)官方和標(biāo)準(zhǔn)版本 1.0 是 2007 年才發(fā)布的。Groovy 的好處在于,它還可以用作腳本語(yǔ)言。Groovy 是一種動(dòng)態(tài)類型語(yǔ)言,所以類型檢查是在運(yùn)行時(shí)進(jìn)行的;這也是一些開(kāi)發(fā)人員不喜歡 Groovy 的原因之一。我們使用 Groovy 編寫(xiě)代碼,在編譯時(shí)看起來(lái)它是正確的,但是在運(yùn)行時(shí),我們才會(huì)發(fā)現(xiàn)其中有問(wèn)題。
圖片來(lái)源:維基百科
接下來(lái)出現(xiàn)了另外一種流行的語(yǔ)言,也就是我們要討論的 Scala。Scala 在 2004 年正式發(fā)布,它為 JVM 領(lǐng)域帶來(lái)了一種新的編程模型,也就是函數(shù)式編程和它的聲明式方法。我們可以確定,Scala 率先引入了不可變性(immutability)的理念,所以它對(duì) Java 的轉(zhuǎn)變做出了重要貢獻(xiàn)。但另一方面,Scala 的批評(píng)者并不喜歡它,因?yàn)樗Z(yǔ)法復(fù)雜,可讀性一般比較差。
圖片來(lái)源:維基百科
JVM 領(lǐng)域出現(xiàn)的下一個(gè)語(yǔ)言是 Clojure,它是一個(gè)純函數(shù)式語(yǔ)言,最近變得非常流行,但是它最早出現(xiàn)于 2007 年。Clojure 是一種基于 LISP 的語(yǔ)言,其特點(diǎn)是簡(jiǎn)單和使用純函數(shù)。在它的缺點(diǎn)中,值得一提的是動(dòng)態(tài)類型(與 Groovy 相同),而且學(xué)習(xí)曲線更陡峭,因?yàn)樗恼Z(yǔ)法與其他 JVM 語(yǔ)言完全不同。如果你對(duì)學(xué)習(xí) Clojure 感興趣的話,那么應(yīng)該閱讀如下這兩本好書(shū):“The joy of Clojure”和“Programming Clojure(第三版)”。
圖片來(lái)源:維基百科
最后但同樣重要的是 Kotlin!Kotlin 在 2016 年 2 月份首次發(fā)布,從那時(shí)開(kāi)始,它就變得不斷流行起來(lái)。該語(yǔ)言是由 JetBrains 公司設(shè)計(jì)的,它有一個(gè)明確的目標(biāo):消除 Java 中所有常見(jiàn)的問(wèn)題。它的設(shè)計(jì)方式保留了 Java 所有的優(yōu)點(diǎn),但是消除了 Java 的大多數(shù)問(wèn)題,這也是它為何如此流行的原因,很多人甚至認(rèn)為在未來(lái)的幾年中它有可能會(huì)擊敗 Java。如果你想要了解 Kotlin 的更多內(nèi)容的話(我鼓勵(lì)你這樣做,因?yàn)樗且婚T(mén)偉大的語(yǔ)言),那么我推薦你閱讀“Kotlin in Action”一書(shū),對(duì)于 Java 開(kāi)發(fā)人員來(lái)說(shuō),這是一本入門(mén) Kotlin 的優(yōu)秀圖書(shū)。
圖片出自 Unsplash 站點(diǎn),作者為 Louis Tsai
這就是最重要的 JVM 語(yǔ)言,我們省略了一些不太流行的 JVM 語(yǔ)言,但是我們可以提一下它們的名字:Jython、JRuby、Ceylon、Fantom 等等。你可以通過(guò)該地址獲取現(xiàn)有 JVM 語(yǔ)言的全部列表。
我們可以發(fā)現(xiàn),在最初的八年或十年間,Java 并沒(méi)有太多的競(jìng)爭(zhēng)對(duì)手,但從那之后,Java 就面臨一些競(jìng)爭(zhēng)了,那么有競(jìng)爭(zhēng)是一件好事兒還是壞事兒呢?
2. 競(jìng)爭(zhēng)加劇帶來(lái)的好處
正如我們?cè)谇拔乃觯琂ava 在早期并沒(méi)有太多改變,這很可能是因?yàn)闆](méi)有改變的必要,盡管它遠(yuǎn)遠(yuǎn)稱不上完美,但也已經(jīng)得到了廣泛的使用。
但是,新的競(jìng)爭(zhēng)者出現(xiàn)了,這些更現(xiàn)代的語(yǔ)言帶來(lái)了新的特性,解決了長(zhǎng)期困擾 Java 開(kāi)發(fā)人員的一些痛點(diǎn)。
舉例來(lái)說(shuō),我們看一下 Scala 語(yǔ)言,自 2009 年以來(lái),Scala 變得越來(lái)越受歡迎,開(kāi)發(fā)人員歡迎這種新的函數(shù)式風(fēng)格,它能夠讓他們的編碼更靈活,也能安全輕松地編寫(xiě)出并行代碼。我們可以在下面的谷歌趨勢(shì)圖中看到這個(gè)趨勢(shì):
圖片來(lái)源:theboreddev.com
那 Oracle 對(duì)這種新趨勢(shì)的反應(yīng)是什么呢?那就是在 2014 年發(fā)布了 Java Lambdas 和 Streams。很多人都認(rèn)為當(dāng)時(shí)這是 Java 擊敗 Scala 的最大舉措。目前行業(yè)中每個(gè)人都能感受到最近幾年 Scala 因?yàn)槿鄙倭魉馐艿膿p失。
JVM 領(lǐng)域中存在競(jìng)爭(zhēng)者的另外一個(gè)好處就是 JIT 編譯器和 JVM 本身正在經(jīng)歷的持續(xù)改進(jìn)?,F(xiàn)在,有更多的人對(duì) JVM 優(yōu)化和性能改善感興趣。所以,競(jìng)爭(zhēng)對(duì)每個(gè)人都是好事。
Kotlin 是這個(gè)領(lǐng)域最新的競(jìng)爭(zhēng)者。Kotlin 非常重要,因?yàn)樗谝欢ǔ潭壬蠟?Oracle 指明了前進(jìn)方向。Kotlin 表明它能夠保持 Java 好的組成部分,同時(shí)創(chuàng)建一個(gè)更簡(jiǎn)潔和快速的編碼語(yǔ)言。
如果看一下谷歌趨勢(shì)的話,我們能夠看到在過(guò)去幾年間,Kotlin 的流行程度:
圖片來(lái)源:theboreddev.com
從圖中可以看出,Kotlin 迅速變得非常流行,但是在最近幾年,它似乎穩(wěn)定了下來(lái)。
Oracle 很好地記錄了業(yè)界對(duì) Kotlin 的反應(yīng),如果你看一下 JDK 15 的發(fā)布說(shuō)明,就會(huì)發(fā)現(xiàn) Java 的一些新特性基本上就是對(duì) Kotlin 變更的復(fù)制。例如,新的 Java record、文本塊(使用三個(gè)引號(hào)的多行字符串)以及 switch 語(yǔ)句(或多或少借鑒了 Kotlin 的 when 語(yǔ)句)。我們可以通過(guò)該地址查閱 JDK 15 的發(fā)布說(shuō)明。
剛才提到的這些,我都將其稱為“Java 的 Kotlin 化(Kotlinisation)”。Kotlin 通過(guò)成為 Java 有史以來(lái)最強(qiáng)的競(jìng)爭(zhēng)對(duì)手,為 Java 指明了發(fā)展的方向。在我看來(lái),Kotlin 是我見(jiàn)過(guò)的唯一一種能夠戰(zhàn)勝 Java,并成為行業(yè)領(lǐng)導(dǎo)者的語(yǔ)言。
3. Java 的“Kotlin”化
Java 的一些新特性主要在可讀性方面進(jìn)行了增強(qiáng),并改善了其主要的一個(gè)弱點(diǎn),那就是繁瑣性。我們可以斷言,它與某些 Kotlin 的特性具有相似性。
需要注意,這些特性大多數(shù)都還處于特性預(yù)覽階段,這意味著你安裝 JDK 14 或 JDK 15 時(shí),默認(rèn)不會(huì)啟用這些特性。
Java 特性預(yù)覽指的是一些在發(fā)布版本中包含、但默認(rèn)禁用的特性。在發(fā)行版中包含它們僅僅是為了收集社區(qū)開(kāi)發(fā)人員的反饋,因此它們更經(jīng)常發(fā)生變更,這也是為何不推薦在生產(chǎn)環(huán)境代碼中使用它們的原因。
要在編譯時(shí)啟用這些特性,我們需要執(zhí)行如下代碼:
- javac --enable-preview --release 14
如果你想要在運(yùn)行時(shí)啟用它們的話,如下執(zhí)行如下代碼:
- Javajava --enable-preview YourClass
當(dāng)然,你也可以在 IDE 中啟用它們,但是不要在你的新項(xiàng)目中默認(rèn)啟用預(yù)覽功能。
我們看一看這些變更,在未來(lái)的 Java 版本中,它們會(huì)對(duì)我們的編碼產(chǎn)生更大的影響。
Java record
Java record 是我們長(zhǎng)期以來(lái)一直要求的一項(xiàng)特性,我相信你早就多次遇到這樣的場(chǎng)景了,那就是極不情愿地實(shí)現(xiàn) toString、hashCode、equals 方法以及每個(gè)字段的 getter(在這里,我假設(shè)你已經(jīng)不再實(shí)現(xiàn) setter 了,還記得我們?cè)?ldquo;Java 中新的并發(fā)模型”一文中所討論的不可變性嗎?)。
Kotlin 提供了數(shù)據(jù)類(data class)來(lái)解決這個(gè)問(wèn)題,Java 也通過(guò)發(fā)布 record 類來(lái)解決了這個(gè)問(wèn)題,同樣的問(wèn)題,Scala 是通過(guò) case 類來(lái)解決的。
這些類的主要目的是在對(duì)象中保存不可變的數(shù)據(jù)。讓我們通過(guò)一個(gè)示例來(lái)看看它在 Java 中能夠帶來(lái)多么好的效果。我們實(shí)例化并對(duì)比 Employee 類,需要編寫(xiě)這么多的代碼:
- package com.theboreddev.java14;
- import java.util.Objects;
- public class Employee {
- private final String firstName;
- private final String surname;
- private final int age;
- private final Address address;
- private final double salary;
- public Employee(String firstName, String surname, int age, Address address, double salary) {
- this.firstName = firstName;
- this.surname = surname;
- this.age = age;
- this.address = address;
- this.salary = salary;
- }
- public String getFirstName() {
- return firstName;
- }
- public String getSurname() {
- return surname;
- }
- public int getAge() {
- return age;
- }
- public Address getAddress() {
- return address;
- }
- public double getSalary() {
- return salary;
- }
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- Employee employee = (Employee) o;
- return age == employee.age &&
- Double.compare(employee.salary, salary) == 0 &&
- Objects.equals(firstName, employee.firstName) &&
- Objects.equals(surname, employee.surname) &&
- Objects.equals(address, employee.address);
- }
- @Override
- public int hashCode() {
- return Objects.hash(firstName, surname, age, address, salary);
- }
- @Override
- public String toString() {
- return "Employee{" +
- "firstName='" + firstName + '\'' +
- ", surname='" + surname + '\'' +
- ", age=" + age +
- ", address=" + address +
- ", salary=" + salary +
- '}';
- }
- }
它所包含的 Address 對(duì)象如下所示:
- package com.theboreddev.java14;
- import java.util.Objects;
- public class Address {
- private final String firstLine;
- private final String secondLine;
- private final String postCode;
- public Address(String firstLine, String secondLine, String postCode) {
- this.firstLine = firstLine;
- this.secondLine = secondLine;
- this.postCode = postCode;
- }
- public String getFirstLine() {
- return firstLine;
- }
- public String getSecondLine() {
- return secondLine;
- }
- public String getPostCode() {
- return postCode;
- }
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- Address address = (Address) o;
- return Objects.equals(firstLine, address.firstLine) &&
- Objects.equals(secondLine, address.secondLine) &&
- Objects.equals(postCode, address.postCode);
- }
- @Override
- public int hashCode() {
- return Objects.hash(firstLine, secondLine, postCode);
- }
- @Override
- public String toString() {
- return "Address{" +
- "firstLine='" + firstLine + '\'' +
- ", secondLine='" + secondLine + '\'' +
- ", postCode='" + postCode + '\'' +
- '}';
- }
- }
為了完成一件簡(jiǎn)單的事情,我們寫(xiě)了太多的代碼,對(duì)不對(duì)?
接下來(lái),我們看一下使用新的 Java record 之后,代碼會(huì)是什么樣子:
- public record EmployeeRecord(String firstName, String surname,
- int age, AddressRecord address, double salary) {
- }
再看一下 Address 類:
- public record AddressRecord(String firstLine, String
- secondLine, String postCode) {
- }
這和我們前面所編寫(xiě)的一大堆代碼是同樣的效果,我們不得不承認(rèn):這非常棒!從要保存的代碼數(shù)量和簡(jiǎn)潔性方面都是如此。
現(xiàn)在我們看看新的 switch 語(yǔ)句有什么不同。
改善 switch 語(yǔ)句
新的 switch 語(yǔ)句解決了在 Java 中使用 switch 語(yǔ)句的一些固有問(wèn)題。我們一直以來(lái)都被教導(dǎo)應(yīng)該避免使用 switch 語(yǔ)句,因?yàn)樗鼈兒苋菀壮鲥e(cuò)并會(huì)導(dǎo)致代碼重復(fù)。舉例來(lái)說(shuō),我們很容易遇到某個(gè) case 條件覆蓋不到的場(chǎng)景。
新的 switch 語(yǔ)句解決了這個(gè)問(wèn)題,因?yàn)槿绻覀兊?switch 語(yǔ)句沒(méi)有涵蓋我們傳遞給它的領(lǐng)域類型的所有范圍,它就無(wú)法編譯通過(guò)。
為了闡述該例子,我們使用 Java 創(chuàng)建一個(gè) DayOfTheWeek 枚舉:
- public enum DayOfTheWeek {
- MONDAY,
- TUESDAY,
- WEDNESDAY,
- THURSDAY,
- FRIDAY,
- SATURDAY,
- SUNDAY
- }
我們需要 switch 語(yǔ)句告訴我們每周的某一天所對(duì)應(yīng)的位置??匆幌峦ㄟ^(guò) Java 11 該怎么實(shí)現(xiàn):
- final DayOfTheWeek dayOfTheWeek = DayOfTheWeek.THURSDAY;
- int position = 0;
- switch (dayOfTheWeek) {
- case MONDAY:
- position = 1;
- break;
- case TUESDAY:
- position = 2;
- break;
- case WEDNESDAY:
- position = 3;
- break;
- case THURSDAY:
- position = 4;
- break;
- case FRIDAY:
- position = 5;
- break;
- case SATURDAY:
- position = 6;
- break;
- case SUNDAY:
- position = 7;
- break;
- }
- System.out.println("Day " + dayOfTheWeek + " is in position " + position + " of the week");
使用原來(lái)的 switch 語(yǔ)句時(shí),我們必須要使用一個(gè)變量,而且如果我們遺漏了一周中的某一天,代碼也能編譯通過(guò)。這就是 switch 語(yǔ)句的問(wèn)題之一,非常容易出錯(cuò)。
Java 14 會(huì)怎樣改善這種情況呢?我們快速看一下:
- final DayOfTheWeek dayOfTheWeek = DayOfTheWeek.THURSDAY;
- int position = switch (dayOfTheWeek) {
- case MONDAY -> 1;
- case TUESDAY -> 2;
- case WEDNESDAY -> 3;
- case THURSDAY -> 4;
- case FRIDAY -> 5;
- case SATURDAY -> 6;
- case SUNDAY -> 7;
- };
- System.out.println("Day " + dayOfTheWeek + " is in position " + position + " of the week");
我們可以看到,新的 switch 語(yǔ)句可以用作表達(dá)式,而不僅僅是語(yǔ)句。
這樣帶來(lái)的結(jié)果就是更加簡(jiǎn)潔,也更具有表述性,這就足以說(shuō)服我們使用它了。但是,現(xiàn)在的 switch 還有一個(gè)重要改善,那就是如果在 switch 中沒(méi)有涵蓋所有 case 的話,它將無(wú)法編譯通過(guò)。它會(huì)顯示如下錯(cuò)誤:
- Error:(9, 24) java: the switch expression does not cover all
- possible input values
現(xiàn)在,我們不會(huì)在 switch 語(yǔ)句中遺漏 case 了,這是一項(xiàng)非常棒的特性。
這非常類似于 Kotlin 的 when 語(yǔ)句,你可以通過(guò)該地址了解該語(yǔ)句的更多信息。
接下來(lái),我們看一下文本塊。
文本塊
你有沒(méi)有遇到過(guò)將一個(gè)大的 blob JSON 賦值給 Java 變量的場(chǎng)景?你是否也受夠了這種丑陋的代碼?Java 將會(huì)引入多行字符串特性,我們可以通過(guò)將它們封裝在三重引號(hào)中來(lái)定義它們。當(dāng)這個(gè)功能被正式發(fā)布后,定義多行長(zhǎng)字符串會(huì)更加容易。
我們來(lái)看一下兩種模式的差異。假設(shè)我們想要將一個(gè)格式化后的 JSON 存儲(chǔ)到一個(gè)變量中,那么丑陋的代碼如下所示:
- final String text = "{\"widget\": {\n" +
- " \"debug\": \"on\",\n" +
- " \"window\": {\n" +
- " \"title\": \"Sample Konfabulator Widget\",\n" +
- " \"name\": \"main_window\",\n" +
- " \"width\": 500,\n" +
- " \"height\": 500\n" +
- " },\n" +
- " \"image\": { \n" +
- " \"src\": \"Images/Sun.png\",\n" +
- " \"name\": \"sun1\",\n" +
- " \"hOffset\": 250,\n" +
- " \"vOffset\": 250,\n" +
- " \"alignment\": \"center\"\n" +
- " },\n" +
- " \"text\": {\n" +
- " \"data\": \"Click Here\",\n" +
- " \"size\": 36,\n" +
- " \"style\": \"bold\",\n" +
- " \"name\": \"text1\",\n" +
- " \"hOffset\": 250,\n" +
- " \"vOffset\": 100,\n" +
- " \"alignment\": \"center\",\n" +
- " \"onMouseUp\": \"sun1.opacity = (sun1.opacity / 100) * 90;\"\n" +
- " }\n" +
- "}} ";
可以更容易地編寫(xiě)整潔的代碼了:
- final String multiLineText = """
- {"widget": {
- "debug": "on",
- "window": {
- "title": "Sample Konfabulator Widget",
- "name": "main_window",
- "width": 500,
- "height": 500
- },
- "image": {\s
- "src": "Images/Sun.png",
- "name": "sun1",
- "hOffset": 250,
- "vOffset": 250,
- "alignment": "center"
- },
- "text": {
- "data": "Click Here",
- "size": 36,
- "style": "bold",
- "name": "text1",
- "hOffset": 250,
- "vOffset": 100,
- "alignment": "center",
- "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
- }
- }}
- """;
我覺(jué)得這樣好太多了。這也是 Kotlin 所支持的,可以在這里的類型定義中找到。
總之,我們能看到 Java 從它的競(jìng)爭(zhēng)對(duì)手之一,也就是 Kotlin,那里“繼承”了許多方案來(lái)解決自己的問(wèn)題。我們不知道這次 Oracle 在對(duì)抗 Kotlin 的崛起方面是否及時(shí)做出了正確的反應(yīng),或許這有點(diǎn)太晚了。但我個(gè)人認(rèn)為 Java 正在朝著正確的方向前進(jìn),盡管這些變化是由它的競(jìng)爭(zhēng)對(duì)手以某種方式觸發(fā)的,而且可能來(lái)得有點(diǎn)遲了。
如前所述,如果這篇文章激發(fā)了你學(xué)習(xí) Kotlin 語(yǔ)言的興趣,我建議你閱讀“Kotlin in Action”,對(duì)于 Java 開(kāi)發(fā)人員來(lái)說(shuō),這是一門(mén)很棒的 Kotlin 入門(mén)圖書(shū)。
4. 結(jié)論
我認(rèn)為競(jìng)爭(zhēng)是 Java 語(yǔ)言有史以來(lái)所遇到的最好的事情。如果不這樣,Java 就會(huì)作繭自縛。Java 的競(jìng)爭(zhēng)對(duì)手也表明了不同的編程方式是可行的,它表明了前進(jìn)的方向,并讓我們避免使用老式的、陳舊的編寫(xiě)代碼方式。
我最近在 Java 中看到了一些變化,以及所有即將發(fā)布的特性和改善,它們正在使 Java 變得比以往任何時(shí)候都更強(qiáng)大。它是一種適應(yīng)當(dāng)前時(shí)代的語(yǔ)言,一種希望發(fā)展并忘記傳統(tǒng)做事方式的語(yǔ)言:Java 的新未來(lái)!