與現(xiàn)代語(yǔ)言相比,Java老套、低效、而且已經(jīng)完蛋了,基本上他們都會(huì)這樣對(duì)我說(shuō)。然而,實(shí)際情況確實(shí)如此嗎?
老套
沒(méi)錯(cuò),Java的基本結(jié)構(gòu)和限制都比較老套,而且還依賴于20年前寫(xiě)代碼的方式。
編程語(yǔ)言并不是憑空產(chǎn)生的,開(kāi)發(fā)人員的習(xí)慣和需求是語(yǔ)言設(shè)計(jì)的核心,雖然語(yǔ)言的發(fā)明者試圖將創(chuàng)新融入其中,但是忽略人們實(shí)際的使用方法是很愚蠢的做法。
Java史上的第一個(gè)里程碑可以追溯到1995年,雖然它的一些基礎(chǔ)模塊的設(shè)計(jì)看起來(lái)至少有10年的遠(yuǎn)見(jiàn),然而很明顯,24年后的今天……看起來(lái)不是那么一碼事了。
但這不僅僅是時(shí)間的問(wèn)題。在過(guò)去的十年中,Java發(fā)生了很多變化。其中一些變化似乎與Java本身無(wú)關(guān),卻無(wú)比重要。
例如,廉價(jià)的內(nèi)存對(duì)于生產(chǎn)軟件中大規(guī)模重新采用函數(shù)編程起著舉足輕重的作用。而這又與反應(yīng)式宣言(The Reactive Manifesto)息息相關(guān)。
便于訪問(wèn)和管理的云計(jì)算促進(jìn)了微服務(wù)模型概念的發(fā)展,這種模型隨著容器的出現(xiàn)走向了生產(chǎn)環(huán)境。
于是,在微服務(wù)模型的發(fā)展中,一些非常適合于某些任務(wù),但在其他任務(wù)上表現(xiàn)平平的編程語(yǔ)言脫穎而出。
編程語(yǔ)言世界的變化遠(yuǎn)不止于此,大數(shù)據(jù)帶來(lái)的新挑戰(zhàn)催生了專門(mén)為處理大數(shù)據(jù)而優(yōu)化過(guò)的新的數(shù)據(jù)庫(kù)系統(tǒng),這些數(shù)據(jù)庫(kù)能夠攝取大量的數(shù)據(jù),然后對(duì)其進(jìn)行分析。
實(shí)際上,這并沒(méi)有催生新的語(yǔ)言,而是為適合于這項(xiàng)任務(wù)的語(yǔ)言找到了另一種使用方式。
更不用說(shuō)人工智能又一次掀起了爭(zhēng)先恐后的熱潮。
但是,等一下......
如今,Python成為了機(jī)器學(xué)習(xí)的黃金標(biāo)準(zhǔn),但是如果快速瀏覽一下它的維基百科頁(yè)面,你就會(huì)發(fā)現(xiàn)Python的誕生早于Java,甚至可以追溯到1990年!
那么R呢?這可是數(shù)據(jù)分析常見(jiàn)的選擇。R語(yǔ)言始于1993年。
那么JavaScript呢?奇怪的是,JavaScript出現(xiàn)于1995年,與Java同年!
Erlang呢?1986年......
為什么沒(méi)人說(shuō)這些語(yǔ)言老套,卻單單說(shuō)Java呢?
因?yàn)槲覀兏淖兞耍€有我們面臨的挑戰(zhàn)也發(fā)生了變化。
例如,Python一直是編寫(xiě)實(shí)用工具和數(shù)據(jù)處理程序的一種出色的腳本語(yǔ)言,但通常我們不認(rèn)為它適合于臃腫的企業(yè)應(yīng)用程序。
然而,一般來(lái)說(shuō)微服務(wù)是一些小程序和數(shù)據(jù)管道,它們由明確定義的功能型小組件組成。
一直以來(lái),JavaScript是動(dòng)態(tài)網(wǎng)頁(yè)的唯一解決方案,但隨著復(fù)雜Web應(yīng)用程序的激增,將JavaScript帶到服務(wù)器端也算合情合理。
總而言之,我們說(shuō)Java老套,只是因?yàn)樗浅_m合構(gòu)建臃腫的單體應(yīng)用,這些應(yīng)用往往擁有數(shù)百萬(wàn)行的代碼量,需要大量的規(guī)劃和嚴(yán)格的順序,而Java的設(shè)計(jì)目的本來(lái)就在于此。
如果試試看用JavaScript構(gòu)建這樣的應(yīng)用,你很快就會(huì)意識(shí)到“死亡不是終點(diǎn) ,而是一種轉(zhuǎn)變”(摘自:夢(mèng)劇院樂(lè)隊(duì)的歌曲《Fatal Tragedy》)。
低效
聽(tīng)上去確實(shí)如此。
我經(jīng)常用下面的比喻來(lái)解釋Java:
如果你需要做一個(gè)火柴盒,那么首先你需要10噸木材,建造一個(gè)小木屋,然后再一點(diǎn)點(diǎn)削成火柴盒。
由于Java強(qiáng)調(diào)用一種正式嚴(yán)謹(jǐn)?shù)姆椒▉?lái)鼓勵(lì)開(kāi)發(fā)人員創(chuàng)建適當(dāng)?shù)念悓哟谓Y(jié)構(gòu),所以開(kāi)發(fā)人員即使覺(jué)得這種做法很白癡,也不得不采用正確的方式設(shè)置所有內(nèi)容,即使對(duì)于一個(gè)非常小的任務(wù)也是如此。
然而,這就是問(wèn)題所在,就像我們上面所說(shuō),Java的任務(wù)都不容易。
請(qǐng)注意,我所說(shuō)的“不容易”指的是不容易實(shí)現(xiàn),但在架構(gòu)方面卻很容易。
編寫(xiě)錯(cuò)綜復(fù)雜的算法是一項(xiàng)艱巨的任務(wù),而且我發(fā)現(xiàn)用Python來(lái)寫(xiě)更容易。
對(duì)于這一點(diǎn),很明顯我們一直在反復(fù)討論同一個(gè)概念:選擇正確的工具。
一直以來(lái),Java都是一種非常通用的編程語(yǔ)言,而且被用于解決各種情況下各種類型的問(wèn)題,但隨著時(shí)間的推移和挑戰(zhàn)的變化,似乎越來(lái)越明顯Java也并非無(wú)所不能——這并不是因?yàn)樗呀?jīng)演變成了一種專門(mén)的語(yǔ)言,而是因?yàn)槠渌Z(yǔ)言更加擅長(zhǎng)處理特定的任務(wù)。
如果你想構(gòu)建一個(gè)大型企業(yè)平臺(tái),其中包含大量的內(nèi)部構(gòu)造,巨大的代碼庫(kù),瘋狂的并行性等等。
那么Java仍然很給力。等一下,真的是這樣嗎……?
Java已經(jīng)完蛋了
也許有點(diǎn)陰暗,但是有一句話說(shuō)的好:“不要害怕未來(lái),你也活不了那么長(zhǎng)。” 你是不是感覺(jué)想笑……
Java就像一名開(kāi)發(fā)人員一樣,隨著時(shí)間流逝一天天老去,你不再像10年前那樣擁有清醒的頭腦,但是你會(huì)變得更聰明、穩(wěn)定和可靠。
當(dāng)然,你仍然可以學(xué)習(xí)Rust,但你永遠(yuǎn)無(wú)法像比你年輕10歲的人那樣,你總覺(jué)得哪里不對(duì)勁。
同樣,Java也在現(xiàn)代化的競(jìng)爭(zhēng)中不斷落后,當(dāng)新功能出現(xiàn)時(shí),你總感覺(jué)在經(jīng)歷了諸多波折后,它們終于成為了現(xiàn)實(shí)。
例如,當(dāng)他們第一次引入lambdas時(shí),你的反應(yīng)不是:“哇!歡呼吧!”,而更像是:“天啊,為什么到現(xiàn)在才出來(lái)啊?”
另一方面,人們沒(méi)有意識(shí)到Java的大成就不在于語(yǔ)言本身。
良好的生態(tài)系統(tǒng)
在規(guī)劃大型軟件時(shí),讓我想起Java的另一個(gè)因素就是Java的生態(tài)系統(tǒng)。無(wú)論是何種互聯(lián)網(wǎng)上你夢(mèng)寐以求的東西,Java都可以為你提供卓越高品質(zhì)的庫(kù)。
想想Spring、Akka、Tomcat等等(我可以說(shuō)出來(lái)幾百個(gè)),這些都不是業(yè)余項(xiàng)目,而是非凡的成就。
我并不是說(shuō)其他語(yǔ)言做不到,但是在大企業(yè)的推動(dòng)下,Java創(chuàng)造了這種軟件生存的先決條件。
此外,一個(gè)良好的生態(tài)系統(tǒng)需要花費(fèi)數(shù)年才能培養(yǎng)起來(lái),時(shí)間因素也非常重要,對(duì)于Java生態(tài)系統(tǒng)成熟來(lái)說(shuō),20年可以說(shuō)是很長(zhǎng)的時(shí)間了。
當(dāng)然,你也可以找到適用于多種語(yǔ)言的特殊庫(kù),但是很快你就會(huì)意識(shí)到這些庫(kù)的存亡,在很大程度上取決于大公司是否認(rèn)可這些項(xiàng)目。
例如,為Python找到好的機(jī)器學(xué)習(xí)庫(kù)非常容易,但你不能否認(rèn)Google在其中發(fā)揮的作用。在Facebook的支持下,你才有了React.js(Javascript)開(kāi)發(fā)出色的Web應(yīng)用程序。
Java大的成就是JVM
除了我們之前提到的龐大生態(tài)系統(tǒng)之外,Java大的成就是JVM。雖然語(yǔ)言可能因年齡的增長(zhǎng)而面臨重重困難,但至少在我看來(lái)JVM很健康。
如今,有人可能會(huì)說(shuō)容器化已經(jīng)削弱了對(duì)JVM的需求,從某種意義上說(shuō),此言非虛。
JVM初的需求是允許程序在所有操作系統(tǒng)上執(zhí)行,但容器改變了一切,因?yàn)樵谌萜鞯膸椭拢覀兛梢约俣ú僮飨到y(tǒng)可以在任何地方運(yùn)行,甚至是紙上。
然而,JVM的作用遠(yuǎn)不止于此。內(nèi)存管理和垃圾收集、安全性、基本編程庫(kù)以及調(diào)試和檢查功能,JVM承擔(dān)起了所有的這些工作,為我們提供了一個(gè)安全舒適的環(huán)境。
人們常常反駁我說(shuō):“但是JVM非常臃腫,非常慢!”雖然從內(nèi)存的占用和引導(dǎo)時(shí)間來(lái)看,這話沒(méi)錯(cuò),然而從性能的角度來(lái)看,過(guò)去的20年中發(fā)生了很多變化。
我們經(jīng)常會(huì)通過(guò)常用的算法,進(jìn)行下述的比較:
Python 3 Vs. Java
Node js Vs. Java
Go Vs. Java
Erlang HiPE Vs. Java
雖然這種比較對(duì)一些語(yǔ)言不太公平,因?yàn)樗惴ㄖ皇切阅芤蛩氐囊徊糠郑珡闹锌梢钥闯鯦VM絕非病入膏肓。
然而…...
從某種程度上,我同意雖然JVM狀況良好,但Java卻在努力保住自己的地位。
Oracle明白這種形式,而且他們正在努力再次將Java推向巔峰,雖然這種做法會(huì)產(chǎn)生一些意想不到的后果,但沒(méi)人能夠阻止老化的過(guò)程。
然而,這也未必是一件壞事。
JVM充當(dāng)了創(chuàng)建效率更高的現(xiàn)代化語(yǔ)言的平臺(tái)。雖然不是很多,但憑良心說(shuō),有一些還是非常成功的。
這就是關(guān)鍵所在。Java這個(gè)霸主并沒(méi)有死,雖然有些咳嗽。然而,它的后代將繼續(xù)傳承它的遺產(chǎn)。
Scala。我的第二個(gè)心中所愛(ài)。這是一種非常強(qiáng)大的語(yǔ)言,它是靜態(tài)類型、面向?qū)ο蟮暮瘮?shù)式編程語(yǔ)言。雖然仍未被廣泛采用,但目前它是值得投資掌握的技術(shù)之一。Scala是Play Framework的實(shí)現(xiàn)語(yǔ)言,它還經(jīng)常和Akka的actor模型搭配使用。
Clojure。一種被廣泛接受的類似于Lisp的語(yǔ)言,以其在并發(fā)計(jì)算方面的強(qiáng)大功能而聞名,它經(jīng)常用于處理龐大的數(shù)據(jù)集。
Groovy。動(dòng)態(tài)編程的腳本語(yǔ)言,我常常覺(jué)得它與Java非常類似。Groovy廣泛用于腳本編寫(xiě),也是支持Grails框架的語(yǔ)言。
Kotlin。雖然后一個(gè)出場(chǎng),但并不是說(shuō)這種語(yǔ)言不重要,它是JetBrains的靜態(tài)類型面向?qū)ο蟮暮瘮?shù)式編程語(yǔ)言,如今是Google Android開(kāi)發(fā)的首選工具。
上述我們討論的不是Java的擴(kuò)展。這些是全新的編程語(yǔ)言,但它們都借鑒了Java,重要的是它們充分利用了JVM和Java生態(tài)系統(tǒng)。
但實(shí)際上......
Java編程語(yǔ)言不會(huì)在近期內(nèi)走向消亡。
不僅因?yàn)榇罅康能浖际怯肑ava編寫(xiě)的,而且無(wú)論你同意與否,它雖然有缺陷,但仍然是一種久經(jīng)考驗(yàn)非常適合于新項(xiàng)目的編程語(yǔ)言。
當(dāng)然,Java承擔(dān)的角色會(huì)發(fā)生變化。從前“你唯一需要的只有Java”,而如今只能在部分領(lǐng)域發(fā)揮作用,但它仍然是堅(jiān)實(shí)可靠的一部分。
雖然我對(duì)Scala非常感興趣,但是我也必須說(shuō)Oracle和社區(qū)在改進(jìn)Java方面做出了很大貢獻(xiàn),我們都享受著這些改進(jìn)帶來(lái)的優(yōu)勢(shì)。
雖然新功能的到來(lái)比我們預(yù)想得晚,但在質(zhì)量上卻沒(méi)得說(shuō)。
畢竟,編程語(yǔ)言發(fā)展緩慢可能意味著被棄用,也可能是成功的標(biāo)志。
既然人們?nèi)绱舜笠?guī)模地使用你的編程語(yǔ)言,那么你就不得不認(rèn)真地對(duì)待所有的重大改變。
你所做的每一步都需要考慮影響的程度,以及向后兼容性的方式。任何問(wèn)題都不能掉以輕心。
總結(jié)
我在這個(gè)領(lǐng)域已經(jīng)很長(zhǎng)時(shí)間了,所以我有理由相信我對(duì)Java這門(mén)編程語(yǔ)言的某些特質(zhì)有了一定的了解。
在過(guò)去10年中,這個(gè)領(lǐng)域的發(fā)展加快了速度,但是這些發(fā)展主要集中在某些領(lǐng)域。
出現(xiàn)這樣的情況時(shí),你可能會(huì)感覺(jué)一切都將發(fā)生變化。這些發(fā)展讓部分人過(guò)于激動(dòng)和興奮,所以他們四處喧嚷。
但是,當(dāng)喧囂過(guò)后,你就可以清楚地看到這些發(fā)展的真實(shí)本質(zhì),并盡力利用好這些發(fā)展。
正如我上述所說(shuō),Java依然是Java,但是坦白地說(shuō),多年來(lái)Java努力達(dá)成的所有輝煌還無(wú)人能及。(相關(guān)推薦:Java多線程面試題)
我想對(duì)你們所有人說(shuō)——無(wú)論是年輕人還是老年人,無(wú)論你喜歡還是討厭Java:享受這個(gè)美妙的科技時(shí)代帶來(lái)的多樣性!