kotlin轉java代碼,Java 二十五載,正在 Kotlin 化!

 2023-10-22 阅读 30 评论 0

摘要:相比 Groovy、Scala、Clojure 等來說,Kotlin 保留了 Java 所有的優點,消除了 Java 存在的大部分問題。這是它為什么如此受歡迎的主要原因,許多人認為它可以在未來幾年取 Java 而代之。kotlin轉java代碼,Java 在問世之初的八到十年里沒有太多的競爭對手

相比 Groovy、Scala、Clojure 等來說,Kotlin 保留了 Java 所有的優點,消除了 Java 存在的大部分問題。這是它為什么如此受歡迎的主要原因,許多人認為它可以在未來幾年取 Java 而代之。

kotlin轉java代碼,Java 在問世之初的八到十年里沒有太多的競爭對手。問世十年后,開始有了一些競爭對手。那么,存在競爭是好是壞呢?

作者 |?The Bored Dev

譯者 | 明明如月,責編 | 沭七

頭圖 | CSDN 下載自東方 IC

出品 | CSDN(ID:CSDNnews)

以下為譯文:

有些人會對 Java 略有微詞,他們批判用 Java 寫代碼非常冗長,很多情況下不得不編寫沒有必要的樣板方法。我一直都非常喜歡 Java,對于這些指控我不敢茍同。

的確,Java 的冗長和大量的樣板方法通常會令人生厭。然而,我們生活的世界并非完美。在大多數情況下,我們不得不兩害相權取其輕。我們都知道 Java 并不完美,但是為什么之前沒有采取任何措施來解決這些問題呢?

我個人看來,Java 之所以較長時間內沒有特別大的改進唯一原因是沒有足夠強勁的競爭對手。在缺乏強有力的競爭對手的情況下,Sun 和 Oracle 先后做出的巨大努力讓 Java 占據了編程語言市場的主導地位。

Java 提供了強類型安全性,非常嚴謹的語言結構,成為很多大型項目的首選編程語言。使用 Java,項目就會變得比較可控。此外,Java 通過虛擬機實現跨平臺是其一大特色和優勢。由于使用著名的 JIT 編譯器,借助它自動性能優化的能力,可以極大程度上降低糟糕代碼的影響,這是很多人選擇使用 Java 編程語言的原因。

然而事情悄悄發生了變化,許多新的編程語言可以在 Java 虛擬機(JVM) 上運行,而且這些編程語言還解決和 Java 中存在的很多問題。不僅如此,這些編程語言入門也相對容易一些。

下面我先簡明扼要地介紹下? JVM 編程語言的發展史。

JVM 編程語言的發展史

在開始的時候我要先聲明一下,由于很多 JVM 編程語言沒有引起廣泛關注和廣泛使用,本文略過了這些編程語言。接下來,讓我們快速了解 JVM 語言的歷史。

很顯然,我們必須從 Java 開始介紹,因為 Java 是 JVM 世界中最古老、最流行的編程語言。

Java 語言是 1995 年 5 月誕生,1996 年 1 月正式發布,已經有了?25?年的歷史。最初,Java 是一種純命令式的編程語言,遵循純粹的面向對象程序設計風格的強類型語言。它的語法在某些方面與 C + + 和 C 語言相似。它可以看作是 C++ 和 C 語言的改進版本,因為用 Java 編寫代碼比用 C 或 C++ 容易得多。不過 Java 代碼冗長是被很多人批評的主要原因。

第二種 JVM 語言是 Groovy。盡管它的第一個官方和標準化版本 1.0 直到 2007 年 1 月才發布,它在 2003 年就已經問世。Groovy 具有腳本語言的優勢。Groovy 是一種動態類型語言,因此到運行時才進行類型檢查,這也是一些開發人員不喜歡 Groovy 的原因之一。如果你使用 Groovy 編寫代碼,編譯時看起來非常正確,某些錯誤直到在運行時才能被發現。

圖源:Groovy 官網

接下來是一種流行了多年的編程語言。可能你已經猜到了,它就是 Scala。Scala 在 2004 年正式發布,它給 JVM 世界帶來了一個新的編程模型,包括函數式編程和聲明式方法。Scala 是第一個引入不變性概念的編程語言,這在 Java 語言的演化中扮演著重要的角色。但是它語法復雜和可讀性不高,導致很多人不喜歡它。

圖源:Scala 官網

在 JVM 世界中出現的下一種語言是 Clojure,它是一種純粹的函數式語言。雖然它早 2007 年就已經問世,但是最近才開始流行。Clojure 是一種基于 Lisp 的語言,其特點是簡單和使用純函數。不過它也有很多缺點如:動態類型(與 Groovy 相同)和陡峭的學習曲線,而且語法與其他 JVM 語言也完全不同。

如果你對 Clojure 感興趣,那么你應該閱讀以下幾本好書: 《The Joy of Clojure[1]》和《Programming Clojure: 3rd Edition[2]》。

Kotlin 雖然放在最后介紹,但它卻非常重要,Kotlin 自 2016 年 2 月首次發布時起,它就一直非常流行。它是由 JetBrains 公司設計,它的設計目標非常明確,消除 Java 的所有問題。在設計的過程中,它保留了 Java 所有的優點,消除了 Java 存在的大部分問題。這是它為什么如此受歡迎的主要原因,許多人認為它可以在未來幾年取 Java 而代之。

圖源:Kotlin 官網

如果你想了解更多 Kotlin 的信息(推薦你學習下 Kotlin,因為它是一種很棒的編程語言),推薦你閱讀《Kotlin in Action》一書,這是一本面向 Kotlin 初學者的經典圖書。

上面介紹了幾個最重要的 JVM 編程語言。但是還有一些不太受歡迎的 JVM 編程語言,如 Jython、 JRuby、 Ceylon、 Fantom 等等。你可以在維基百科中查看 JVM 編程語言列表[3]。

值得一提的是,Java 在問世之初的八到十年里沒有太多的競爭對手。問世十年后,開始有了一些競爭對手。那么,存在競爭是好是壞呢?

競爭加劇的好處

正如我們之前提到的,Java 在早期并沒有太大改變。盡管 Java 還遠遠不夠完美,但是它使用非常廣泛,非常流行。

后來出現了新的競爭對手,更多的現代語言帶來了新的特性,解決了 Java 開發人員長期以來一直面臨的一些問題。

如 Scala 語言,自 2009 年以來,它受歡迎程度一直在上升。開發人員對這種新的函數式風格非常歡迎,這種風格使他們能夠更加靈活地編寫并行代碼。我們可以在下面的 Google Trends 中看到這種趨勢:

那么 Oracle 對這一新趨勢的反應如何?2014 年為 Java 添加了 Lambda 表達式和 Stream 特性。這一舉措是 Java 在擊敗 Scala 方面邁出了最大的一步。目前軟件開發行業工作的人都能感受到 Scala 近年來漲勢減緩。

在 JVM 世界中擁有更多競爭對手的另一個好處是 JIT 編譯器和 JVM 本身不斷改進。現在有更多的人對 JVM 本身的優化和 Java 的性能改進非常感興趣。所以從這方面來看,競爭的確是一件好事!

最后一個出現在競技場上的競爭對手是 Kotlin,而 Kotlin 一直非常重要,因為在某種程度上,它為 Oracle 指明了方向。Kotlin 已經證明,在保留 Java 的優點的前提下,創建一種更簡潔的語言來加快編碼速度的可行性。

如果我們看看 Google Trends,就會發現 Kotlin 在過去幾年里有多么受歡迎:

從上圖可以看出 Kotlin 很快就流行起來了。然而,在最近幾年,它似乎已經趨于穩定。

Oracle 也注意到了業內對 Kotlin 的反應。如果你看一下 JDK 15 的發行說明,你會發現 Java 的一些新特性都是借鑒自 Kotlin。示例包括新的 Java 記錄、新的文本塊(帶有三重引號的多行字符串)和新的 switch 語句(或多或少借鑒了 Kotlin 的 when 語句)。

我稱上面的這種現象為「Java 的 Kotlin 化」。Kotlin 變成了 Java 強有力的競爭對手,Kotlin 也為 Java 指明了發展方向。在我看來,Kotlin 是我見過的唯一一種能夠超越 Java 成為行業領導者的語言。

Kotlin 化的 Java

即將發布的 Java 語言新特性在改進可讀性和簡化代碼方面做出了很大改進。我們可以看到,這些新特性和 Kotlin 得到很多特性非常類似。

下面只是功能預覽,這意味著,如果你在 JDK 14 或 JDK 15 發布時安裝它們,默認情況下無法使用它們。

Java 特性預覽是在一個發行版中引入的新特性,但默認是禁用的。它們被包含在發行版中只是為了收集來自開發人員社區的反饋,因此還有變更的可能性。這也是為啥不推薦在生產環境中使用這些特性的重要原因。

如果想要在編譯時啟用它們,您必須執行以下操作:

javac?--enable-preview?--release?14

如果你想在運行時啟用它們,你必須運行以下命令:

java?--enable-preview?YourClass

當然,你也可以在 IDE 中啟用這些特性,但是請注意不要在所有新項目中默認啟用預覽!

接下來讓我們來看看這些變化。這些變化可能對我們未來使用 Java 新版本編碼產生巨大影響。

  • Java 記錄

Java 記錄(records)是我們許多人長期以來一直期盼的一個特性。我想你經常會遇到不得不實現 toString、hashCode、equals 和 getter 方法的情況(我假設你已經不再使用 setter 方法,實際上不應該使用)。

Kotlin 提供了數據類[4]來解決這個問題,Java 也打算通過發布記錄類來實現相同的功能,Scala 的 case 類也有這個功能。

這些類的主要用途是在對象中保存不可變數據。讓我們通過一個例子來看看它在 Java 中的用法。如果我們想要實例化和比較我們的 Employee 類,就需要寫下面的代碼:

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;}@Overridepublic?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);}@Overridepublic?int?hashCode()?{return?Objects.hash(firstName,?surname,?age,?address,?salary);}@Overridepublic?String?toString()?{return?"Employee{"?+"firstName='"?+?firstName?+?'\''?+",?surname='"?+?surname?+?'\''?+",?age="?+?age?+",?address="?+?address?+",?salary="?+?salary?+'}';}
}

上面類中還包含 Address 成員屬性,它的類結構如下:

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;}@Overridepublic?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);}@Overridepublic?int?hashCode()?{return?Objects.hash(firstLine,?secondLine,?postCode);}@Overridepublic?String?toString()?{return?"Address{"?+"firstLine='"?+?firstLine?+?'\''?+",?secondLine='"?+?secondLine?+?'\''?+",?postCode='"?+?postCode?+?'\''?+'}';}
}

相對于要實現的簡單功能來說,這些代碼太長了,難道不是嗎?

現在讓我們看看使用 Java 的記錄后的代碼:

public?record?EmployeeRecord(String?firstName,?String?surname,?int?age,?AddressRecord?address,?double?salary)?{
}

Address 類:

public?record?AddressRecord(String?firstLine,?String?secondLine,?String?postCode)?{
}

這和我們前面冗長的代碼的功能等價。通過對比你可以發現,使用記錄這一特性,代碼減少了很多而且寫起來更簡單。

  • 改進的 switch 語句

Java 改進的 switch 語句解決了在 Java 中使用 switch 語句的一些固有問題。其實之前的版本應該始終避免使用 switch 語句,因為非常容易出錯并容易導致代碼重復。case 很容易遺漏,使用改進的 switch 語句就不存在這個問題。因為如果 switch 語句不覆蓋傳遞給 switch 的類型域的范圍,那么就無法編譯通過。

接下來我們將用一個例子來解釋這個問題。

我們需要先創建一個 DayOfTheWeek 枚舉類:

public?enum?DayOfTheWeek?{MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY
}

如果我們想編寫星期幾在一周的位置,使用 Java 11 可以這么寫:

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");

像上面這樣使用 switch 語句,我們必須引入一個變量,如果我們漏寫了一周的某一天,我們的代碼依然可以完美地編譯通過。這是 switch 語句的問題之一,即非常容易出錯。

那么 Java 14 是如何改善這種情況的呢?

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 語句可以用作表達式,而不僅僅是語句。

這樣做更簡潔而且更有表現力,足以吸引大多數人使用這一特性。如果我們不能涵蓋 switch 中的所有 case,那么 swtich 語句將不能編譯。將報如下的錯誤:

Error:(9,?24)?java:?the?switch?expression?does?not?cover?all?possible?input?values

使用改進的 switch 特性,就不會在 switch 中遺漏 case 條件。

這非常棒,難道不是嗎?

這與 Kotlin 的 when 語句非常相似,你可以在此文[5]中了解相關用法。

下面我們介紹文本塊特性。

  • 文本塊

你有沒有抱怨過在 Java 中給一個變量分配一大塊 JSON 是多么的難以處理?Java 將引入多行字符串,你可以通過將它們包裝在三引號之間來定義它們。當這個特性正式發布時,在多行中定義長字符串就容易多了。

讓我們來看看這兩種模式之間的區別。目前,如果我們想在一個變量中存儲一個格式化的 JSON 字符串,就會像下面這個一樣丑陋:

inal?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"?+"}}?";

當新的文本塊發布時,它會像下面這樣簡單干凈:

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;"}}}""";

我覺得這樣好多了,你同意嗎?這也是 Kotlin 支持的,你可以在它的類型定義中找到。

所以我們看到 Java 從它的競爭對手 Kotlin 那里學到了許多解決自身問題的方案。我們不知道這一次 Oracle 應對?Kotlin 崛起的動作是不是有點晚了。就我個人而言,雖然這些變化是由它的競爭對手激發的,而且有些晚,但是我仍然認為 Java 正在穩步前進。

如前所述,如果這篇文章激發了您學習 Kotlin 語言的興趣,我建議您閱讀《Kotlin in Action》 ,這是一本非常適合Java 開發人員初學 Kotlin 的書。

總結

我認為競爭對 Java 的發展來說是一件好事。如果沒有競爭,Java 很容易滿足于現有的成就而裹足不前。此外,Java 的競爭對手探索了多種編程方式,避免一直停留在陳舊的固有的編碼方式上。

Java 最近的變化以及即將問世的新特性和改進,使得 Java 比任何時候都強大。作為一個適應時代發展要求,敢于走出舒適區的編程語言, Java 將會迎來新的發展機遇。

[1] https://www.manning.com/books/the-joy-of-clojure-second-edition

[2] https://www.amazon.com/dp/1680502468/

[3] https://en.wikipedia.org/wiki/List_of_JVM_languages

[4] https://kotlinlang.org/docs/reference/data-classes.html

[5] https://kotlinlang.org/docs/reference/control-flow.html

英文:A New Future for Java

鏈接:https://medium.com/better-programming/a-new-future-for-java-b10a6789f962

作者:The Bored Dev

譯者:明明如月,知名互聯網公司 Java 高級開發工程師,CSDN 博客專家。

本文為 CSDN 翻譯,轉載請注明來源出處。

【END】

更多精彩推薦
?征戰云時代,為什么安全是關鍵命題?
?連按 5 次 Shift 重改 CMD 和密碼并重啟電腦,這個漏洞你不能不知道!
?Docker 禁止被列入美國“實體名單”的國家、企業、個人使用
?TikTok算法背后是抖音用戶數據?想多了
?移動云2020 H1營收44.57億元,同比增長556.4%
?贈書 | 區塊鏈+互聯網:互信社會崛起
點分享點點贊點在看

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/3/161061.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息