為Java說(shuō)句公道話
有些人問(wèn)我,在現(xiàn)有的語(yǔ)言里面,有什么好的推薦?我說(shuō):“Java。” 他們很驚訝:“什么?Java!” 所以我現(xiàn)在來(lái)解釋一下。
也許是因?yàn)槟贻p人的逆反心理,人們都不把自己的入門(mén)語(yǔ)言當(dāng)回事。很早的時(shí)候,計(jì)算機(jī)系的學(xué)生用Scheme或者Pascal入門(mén),現(xiàn)在大部分學(xué)校用Java。這也許就是為什么很多人恨Java,瞧不起用Java的人。提到Java,感覺(jué)就像是爺爺那輩人用的東西。他們說(shuō),Java老氣,龐大,復(fù)雜,臃腫。
某些Python程序員,在論壇里跟初學(xué)者講解Python有什么好,其中一個(gè)原因竟然是:“因?yàn)镻ython不是Java!” 他們喜歡這樣宣傳:“看Python多簡(jiǎn)單清晰啊,都不需要寫(xiě)類型……” 對(duì)于Java的無(wú)緣無(wú)故的恨,盲目的否認(rèn),導(dǎo)致了他們看不到Java很重要的優(yōu)點(diǎn),以至于迷失自己的方向。雖然氣勢(shì)上占上風(fēng),然而其實(shí)Python作為一個(gè)編程語(yǔ)言,是完全無(wú)法和Java抗衡的。
在性能上,Python比Java慢幾十倍。由于缺乏靜態(tài)類型等重要設(shè)施,Python代碼有bug很不容易察覺(jué),察覺(jué)了也不容易debug,所以Python無(wú)法用于構(gòu)造大規(guī)模的,復(fù)雜的系統(tǒng)。你也許發(fā)現(xiàn)某些startup公司的主要代碼是Python寫(xiě)的,然而這些公司的軟件,質(zhì)量其實(shí)相當(dāng)?shù)牡汀T诔墒斓墓纠铮琍ython最多只用來(lái)寫(xiě)工具性質(zhì)的東西,或者小型的,不會(huì)影響系統(tǒng)可靠性的腳本。
靜態(tài)類型的缺乏,也導(dǎo)致了Python不可能有很好的IDE支持,你不能完全可靠地重構(gòu)(refactor)Python代碼。PyCharm對(duì)于早期的Python編程環(huán)境,是一個(gè)很大的改進(jìn),然而理論決定了,它不可能完全可靠地達(dá)到“變量換名”等基本的refactor操作。
在設(shè)計(jì)上,Python,Ruby比起Java,其實(shí)復(fù)雜很多。缺少了很多重要的特性,有毛病的“強(qiáng)大特性”倒是多了一堆。由于盲目的推崇所謂“正宗的面向?qū)ο?rdquo;方式,所謂“late-binding”,這些語(yǔ)言里面有太多可以“重載”語(yǔ)義的地方,不管什么都可以被重定義,這導(dǎo)致代碼具有很大的不確定性和復(fù)雜性。Python和Ruby代碼很容易被濫用,不容易理解,容易寫(xiě)得很亂,容易出問(wèn)題。
很多JavaScript程序員也盲目地鄙視Java,而其實(shí)JavaScript比Python和Ruby還要差。不但具有它們的所有缺點(diǎn),而且缺乏很多必要的,方便的特性,比如基本的class定義都沒(méi)有。JavaScript的各種“WEB框架”,層出不窮,似乎一直在推陳出新,而其實(shí)呢,全都是在黑暗里瞎蒙亂撞。JavaScript的社區(qū)以幼稚著稱。你經(jīng)常發(fā)現(xiàn)一些非常基本的常識(shí),被JavaScript“專家”們當(dāng)成了不起的發(fā)現(xiàn)似的,在大會(huì)上宣講。我看不出來(lái)JavaScript社區(qū)開(kāi)那些會(huì)議,到底有什么意義,仿佛只是為了拉關(guān)系找工作。
Python湊合可以用在不重要的地方,Ruby是垃圾,JavaScript是垃圾中的垃圾。原因很簡(jiǎn)單,因?yàn)镽uby和JavaScript的設(shè)計(jì)者,其實(shí)都只是民科。
Java的“繼承人”沒(méi)能超越它最近一段時(shí)間,很多人熱衷于Scala,Clojure,Go等新興的語(yǔ)言,他們以為這些是比Java更現(xiàn)代,更先進(jìn)的語(yǔ)言,以為它們最終會(huì)取代Java。然而這些狂熱分子們逐漸發(fā)現(xiàn),Scala,Clojure和Go其實(shí)并沒(méi)有解決它們聲稱能解決的問(wèn)題,反而帶來(lái)了它們自己的毛病。這些毛病很多是Java沒(méi)有的。
關(guān)于Go,我已經(jīng)評(píng)論過(guò)很多了,有興趣的人可以看這里。總之,Go是民科加自大狂的產(chǎn)物,這里我就不多說(shuō)它了。
我認(rèn)識(shí)一些人,開(kāi)頭很推崇Scala,仿佛什么救星似的。我建議他們別去折騰了,老老實(shí)實(shí)用Java。沒(méi)聽(tīng)我的,結(jié)果到后來(lái),成天都在罵Scala的各種毛病。但是沒(méi)辦法啊,項(xiàng)目上了賊船,不得不繼續(xù)用下去。我不喜歡進(jìn)行人身攻擊,然而我發(fā)現(xiàn)一個(gè)語(yǔ)言的好壞,往往取決于它的設(shè)計(jì)者的水平,人品,和動(dòng)機(jī)。很多時(shí)候我看人的直覺(jué)是異常的準(zhǔn),以至于依據(jù)對(duì)語(yǔ)言設(shè)計(jì)者的第一印象,我就能預(yù)測(cè)到這個(gè)語(yǔ)言將來(lái)會(huì)怎么發(fā)展。在這里,我想談一下對(duì)Scala和Clojure的設(shè)計(jì)者的看法。
Scala的設(shè)計(jì)者M(jìn)artin Odersky,雖然在程序語(yǔ)言領(lǐng)域有所建樹(shù),發(fā)表了不少看似高深的學(xué)術(shù)論文( 其實(shí)很多是扯淡的),然而他對(duì)于語(yǔ)言的“設(shè)計(jì)”,其實(shí)并不是特別在行。所以我很驚訝的發(fā)現(xiàn),有些非常基本的東西,Scala都會(huì)搞錯(cuò)。由于Odersky是大學(xué)教授,名聲在外,很多人想找他拿個(gè)PhD,所以東拉西扯的,喜歡往Scala里面加入一些不明不白,有潛在問(wèn)題的“特性”,其目的就是發(fā)paper,混畢業(yè)。這導(dǎo)致Scala過(guò)度繁復(fù),加入的特性很多后來(lái)被證明沒(méi)有多大用處,反而帶來(lái)了問(wèn)題。學(xué)生把代碼實(shí)現(xiàn)加入到Scala的編譯器,畢業(yè)就走人不管了,所以Scala編譯器里,就留下一堆堆的歷史遺留垃圾和bug。
再來(lái)說(shuō)一下Clojure。當(dāng)Clojure最初“橫空面世”的時(shí)候,有些人熱血沸騰地向我推薦。于是我看了一下它的設(shè)計(jì)者Rich Hickey做的宣傳講座視頻。當(dāng)時(shí)我就對(duì)他一知半解拍胸脯的本事,印象非常的深刻。Rich Hickey真的是半路出家,連個(gè)CS學(xué)位都沒(méi)有。可他那種氣勢(shì),仿佛其他的語(yǔ)言設(shè)計(jì)者什么都不懂,只有他看到了真理似的。不過(guò)也只有這樣的人,才能創(chuàng)造出“宗教”吧?Clojure大力宣傳的“特性”(什么lazy啊,pure啊,transactional memory啊),都是從別的語(yǔ)言道聽(tīng)途說(shuō)抄過(guò)來(lái),卻又沒(méi)能深刻理解其精髓。有些“函數(shù)式語(yǔ)言”的特性,本來(lái)就是有問(wèn)題的,卻不問(wèn)青紅皂白,為了“主義正確”,抄過(guò)來(lái)。所以最后你發(fā)現(xiàn)這語(yǔ)言是掛著羊頭賣(mài)狗肉,說(shuō)得頭頭是道,用起來(lái)怎么就那么蹩腳。
Clojure的社區(qū),一直忙著從Scheme和Racket的社區(qū)抄襲思想,卻又想標(biāo)榜是自己的發(fā)明。比如Typed Clojure,就是原封不動(dòng)抄襲Typed Racket。有些一模一樣的基本概念,在Scheme里面都幾十年了,恁是要改個(gè)不一樣的名字,免得你們發(fā)現(xiàn)那是Scheme先有的。甚至有人把SICP,The Little Schemer等名著里的代碼,全都用Clojure改寫(xiě)一遍,結(jié)果完全失去了原作的簡(jiǎn)單性和精華性。最后你發(fā)現(xiàn),Clojure里面好的地方,全都是Scheme已經(jīng)有的,Clojure里面新的特性,幾乎全都有問(wèn)題。我參加過(guò)一些Clojure的meetup,可是后來(lái)發(fā)現(xiàn),里面竟是各種喊著大口號(hào)的初學(xué)者,各種趾高氣昂的民科,愚昧之至。
盲目推崇Scala和Clojure的人們,很多最后都發(fā)現(xiàn),這些語(yǔ)言里面的“新特性”,幾乎都有毛病。它們里面最重要最有用的特性,其實(shí)早就已經(jīng)在Java里了。有些人跟我說(shuō):“你看,Java做不了這件事情!” 后來(lái)經(jīng)我分析,發(fā)現(xiàn)他們?cè)跐撘庾R(shí)里早已死板的認(rèn)定,非得用某種最新最酷的語(yǔ)言特性,才能達(dá)到目的。Java沒(méi)有這些特性,他們就以為Java做不了,非得用另外的語(yǔ)言。其實(shí),如果你換一個(gè)角度來(lái)看問(wèn)題,不要鉆牛角尖,專注于解決問(wèn)題,而不是去追求最新最酷的“寫(xiě)法”,你就能用Java解決它,而且解決得干凈利落。
如果現(xiàn)在要做一個(gè)系統(tǒng),真的寧可用Java,也不要浪費(fèi)時(shí)間去折騰什么Scala或者Clojure。錯(cuò)誤的人設(shè)計(jì)了錯(cuò)誤的語(yǔ)言,拿出來(lái)浪費(fèi)大家的時(shí)間。
Java沒(méi)有特別討厭的地方Java也許缺少一些方便的特性,然而長(zhǎng)久以來(lái)用Java進(jìn)行教學(xué),用Java工作,用Java開(kāi)發(fā)PySonar,RubySonar,Yin語(yǔ)言,…… 我發(fā)現(xiàn)Java其實(shí)并不像很多人傳說(shuō)的那么可惡。我發(fā)現(xiàn)自己想要的95%以上的功能,在Java里面都能找到比較直接的用法。剩下的5%,用稍微笨一點(diǎn)的辦法,一樣可以解決問(wèn)題。
很多人討厭Java,其實(shí)是因?yàn)樵缙诘腉oF Design Patterns,試圖提出千篇一律的模板,給程序帶來(lái)了不必要的復(fù)雜性。然而Java語(yǔ)言本身,其實(shí)跟Design Patterns并不是等價(jià)的。Java的設(shè)計(jì)者跟Design Pattern的設(shè)計(jì)者,完全是不同的人。你完全可以使用Java寫(xiě)出非常簡(jiǎn)單的代碼,而不使用Design Patterns。
Java有優(yōu)秀的IDE支持我平時(shí)都用IntelliJ來(lái)寫(xiě)Java代碼。我發(fā)現(xiàn)IntelliJ里面,有一些非常好的設(shè)計(jì)思想。其中很多功能,其實(shí)超越了所有的文本編輯器(Emacs,VIM……)。IntelliJ讓Java如虎添翼,開(kāi)發(fā)起來(lái)感覺(jué)是在飛一樣。
用IntelliJ的時(shí)候,你不需要為“給變量起名字”之類的事情焦慮。因?yàn)镮ntelliJ有非常強(qiáng)大而友好的refactor功能,你可以非常迅速的換掉變量的名字。所以在第一次創(chuàng)造變量的時(shí)候,你不需要花心思去起一個(gè)完美的名字。用一個(gè)還算湊合的名字,把代碼很快寫(xiě)出來(lái),實(shí)驗(yàn)成功。然后再返回去看代碼,把名字換成一個(gè)更合適的就可以。
IntelliJ還可以進(jìn)行非常迅速的結(jié)構(gòu)變換,這讓你就像藝術(shù)家在構(gòu)造一個(gè)雕塑作品。最開(kāi)頭我可以大刀闊斧,把代碼劈成大致的形狀,然后再把它仔細(xì)推敲,揉捏成更好,更容易理解,更具魅力的形狀。
結(jié)論我實(shí)在不忍心看著有些人被Scala和Clojure忽悠。如果沒(méi)有超級(jí)高的性能和資源需求(可能要用C這樣的低級(jí)語(yǔ)言),目前我建議就老老實(shí)實(shí)用Java吧。雖然不如一些新的語(yǔ)言炫酷,然而實(shí)際的系統(tǒng),還真沒(méi)有什么是Java寫(xiě)不出來(lái)的。少數(shù)地方可能需要繞過(guò)一些限制,或者放寬一些要求,然而這樣的情況不是很多。
編程使用什么工具是重要的,然而工具終究不如自己的技術(shù)重要。很多人花了太多時(shí)間,折騰各種新的語(yǔ)言,希望它們會(huì)奇跡一般的改善代碼質(zhì)量,結(jié)果最后什么都沒(méi)做出來(lái)。選擇語(yǔ)言最重要的條件,應(yīng)該是“夠好用”就可以,因?yàn)轫?xiàng)目的成功最終是靠人,而不是靠語(yǔ)言。
相關(guān)文章:
1. CSS3實(shí)例分享之多重背景的實(shí)現(xiàn)(Multiple backgrounds)2. 使用Spry輕松將XML數(shù)據(jù)顯示到HTML頁(yè)的方法3. php網(wǎng)絡(luò)安全中命令執(zhí)行漏洞的產(chǎn)生及本質(zhì)探究4. XHTML 1.0:標(biāo)記新的開(kāi)端5. ASP基礎(chǔ)知識(shí)VBScript基本元素講解6. 利用CSS3新特性創(chuàng)建透明邊框三角7. XML入門(mén)的常見(jiàn)問(wèn)題(四)8. asp(vbscript)中自定義函數(shù)的默認(rèn)參數(shù)實(shí)現(xiàn)代碼9. 詳解CSS偽元素的妙用單標(biāo)簽之美10. HTML5 Canvas繪制圖形從入門(mén)到精通
