Java,一個從名字聽起來就老叩叩的語言,為什麼要選擇它?其中一個優點,就是它夠「老」,擁有許多外部支援的函式庫、框架與學習資源。上網 Google 也容易獲得解答,以及跨平台支援,讓你「寫一次」就能在許多地方無縫使用。

最後來個實際的,在 104 搜尋 Java 共有將近 5,000 筆工作,什麼都是假的,找到工作才是真的啊!

(責任編輯:陳君毅)

作者:正義的花生

有些人問我,在現有的語言裡面,有什麼好的推薦?我說:「Java。」他們很驚訝:「什麼?Java!」所以我現在來解釋一下。

Java 超越了所有咒罵它的「動態語言」

也許是因為年輕人的逆反心理,人們都不把自己的入門語言當回事。很早的時候,計算機系的學生用 Scheme 或者 Pascal 入門,現在大部分學校用 Java。這也許就是為什麼很多人恨 Java,瞧不起用 Java 的人。

提到 Java,感覺就像是爺爺那輩人用的東西。大家都會用 Java,怎麼能顯得我優秀出眾呢?於是他們說:「Java 老氣、龐大、複雜、臃腫。我更願意探索新的語言……」

某些 Python 工程師,在論壇裡跟初學者講解 Python 有什麼好,其中一個原因竟然是:「因為 Python 不是 Java!」他們喜歡這樣宣傳:「看 Python 多簡單清晰啊,都不需要寫類型… …」對於 Java 的無緣無故的恨,盲目的否認,導致了他們看不到它很重要的優點,以至於迷失自己的方向。

雖然氣勢上佔上風,然而其實 Python 作為一個程式語言,是完全無法和 Java 抗衡的。

在性能上,Python 比 Java 慢幾十倍。由於缺乏靜態類型等重要設施,Python 代碼有 bug 很不容易發現,發現了也不容易 debug,所以 Python 無法用於構造大規模的、複雜的系統。

你也許發現某些 startup 公司的主要代碼是 Python 寫的,然而這些公司的軟體,質量其實相當的低。在成熟的公司裡,Python 最多只用來寫工具性質的東西,或者小型的,不會影響系統可靠性的腳本。

靜態類型的缺乏,也導致了 Python 不可能有很好的 IDE 支持,你不能完全可靠地「跳轉到定義」,不可能完全可靠地重構(refactor)Python 代碼。PyCharm 對於早期的 Python 編程環境,是一個很大的改進,然而理論決定了,它不可能完全可靠地進行「變量換名」等基本的重構操作。

就算是比 PyCharm 強大很多的 PySonar,對此也無能為力。由於 Python 的設計過度的「動態」,沒有類型標記,使得完全準確的定義查找,成為了不可判定(undecidable)的問題。

在設計上,Python、Ruby 比起 Java,其實複雜很多。缺少了很多重要的特性,有毛病的「強大特性」倒是多了一堆。

由於盲目的推崇所謂「正宗的面向對象」方式,所謂“ late binding ”,這些語言裡面有太多可以「重載」語義的地方,不管什麼都可以被重定義,這導致代碼具有很大的不確定性和復雜性,很多 bug 就是被隱藏在這些被重載的語言結構裡面了。因此,Python 和 Ruby 代碼很容易被濫用,不容易理解,容易寫得很亂,容易出問題。

很多 JavaScript 工程師也盲目地鄙視 Java,而其實 JavaScript 比 Python 和 Ruby 還要差。不但具有它們的幾乎所有缺點,而且缺乏一些必要的設施。JavaScript 的各種「WEB 框架」,層出不窮,似乎一直在推陳出新,而其實呢,全都是在黑暗裡瞎蒙亂撞。JavaScript 的社區以幼稚和愚昧著稱。

你經常發現一些非常基本的常識,被 JavaScript「專家」們當成了不起的發現似的,在大會上宣講。我看不出來 JavaScript 社區開那些會議,到底有什麼意義,彷彿只是為了拉關係找工作。

Python 湊合可以用在不重要的地方,Ruby 是垃圾,JavaScript 是垃圾中的垃圾。原因很簡單,因為 Ruby 和 JavaScript 的設計者,其實都是一知半解的民間科學家。然而世界就是這麼奇怪,一個徹底的垃圾語言,仍然可以宣稱是「工程師最好的朋友」,從而得到某些人的愛戴……

Java 的「繼承人」沒能超越它

最近一段時間,很多人熱衷於 Scala、Clojure、Go 等新興的語言,他們以為這些是比 Java 更現代,更先進的語言,以為它們最終會取代 Java。然而這些狂熱分子們逐漸發現,Scala、Clojure 和 Go 其實並沒有解決它們聲稱能解決的問題,反而帶來了它們自己的毛病,而這些毛病很多是 Java 沒有的。然後他們才意識到,Java 離壽終正寢的時候,還遠得很……

● Go 語言

關於 Go,我已經評論過很多了,有興趣的人可以看這裡。總之,Go 是民間科學家加自大狂的產物,奇葩得不得了。這裡我就不多說它了,只談談 Scala 和 Clojure。

Scala

我認識一些人,開頭很推崇 Scala,彷彿什麼救星似的。我建議他們別去折騰了,老老實實用 Java。沒聽我的,結果到後來,成天都在罵 Scala 的各種毛病。但是沒辦法啊,項目上了賊船,不得不繼續用下去。

我不喜歡進行人身攻擊,然而我發現一個語言的好壞,往往取決於它的設計者的背景、覺悟、人品和動機。很多時候我看人的直覺是異常的準,以至於依據對語言設計者的第一印象,我就能預測到這個語言將來會怎麼發展。在這裡,我想談一下對 Scala 和 Clojure 的設計者的看法。

Scala 的設計者 Martin Odersky,在 PL 領域有所建樹,發表了不少學術論文(包括著名的《The Call-by-Need Lambda Calculus》),而且還是大名鼎鼎的Niklaus Wirth的門徒,我因此以為他還比較靠譜。可是開始接觸 Scala 沒多久,我就很驚訝的發現,有些非常基本的東西,Scala 都設計錯了。

這就是為什麼我幾度試圖採用 Scala,最後都不了了之。因為我一邊看,一邊發現讓人跌眼鏡的設計失誤,而這些問題都是 Java 沒有的。這樣幾次之後,我就對 Odersky 失去了信心,對 Scala 失去了興趣。

回頭看看 Odersky 那些論文的本質,我發現雖然理論性貌似很強,其實很多是在故弄玄虛(包括那所謂的“call-by-need lambda calculus”)。他雖然對某些特定的問題有一定深度​​,然而知識面其實不是很廣,眼光比較片面。

對於語言的整體設計,把握不夠好。感覺他是把各種語言裡的特性,強行拼湊在一起,並沒有考慮過它們是否能夠「和諧」的共存,也很少考慮「可用性」。

由於 Odersky 是大學教授,名聲在外,很多人想找他拿個 PhD,所以東拉西扯,喜歡往 Scala 裡面加入一些不明不白,有潛在問題的「特性」,其目的就是發 paper、混畢業。

這導致 Scala 不加選擇的加入過多的特性,過度繁複。加入的特性很多後來被證明沒有多大用處,反而帶來了問題。學生把代碼實現加入到 Scala 的編譯器,畢業就走人不管了,所以 Scala 編譯器裡,就留下一堆堆的歷史遺留垃圾和 bug。這也許不是 Odersky 一個人的錯,然而至少說明他把關不嚴,或者品位確實有問題。

最有名的採用 Scala 的公司,無非是 Twitter。其實像 Twitter 那樣的系統,用 Java 照樣寫得出來。Twitter 後來怎麼樣了呢?CEO 都跑了:P 新 CEO 上台就裁員 300 多人,包括工程師在內。

我估計 Twitter 裁員的一個原因是,有太多的 Scala 工程師,扯著各種高大上不實用的口號,比如「函數式編程」,進行過度工程、浪費公司的資源。花著公司的錢,開著各種會議,組織各種 meetup 和 hackathon,提高自己在 open source 領域的威望,其實沒有為公司創造很多價值……

Clojure

再來說一下 Clojure。當 Clojure 最初「橫空面世」的時候,有些人熱血沸騰地向我推薦。於是我看了一下它的設計者 Rich Hickey 做的宣傳講座影片。當時我就對他一知半解拍胸脯的本事,印象非常的深刻。

Rich Hickey 真的是半路出家,連個 CS 學位都沒有。可他那種氣勢,彷彿其他的語言設計者什麼都不懂,只有他看到了真理似的。不過也只有這樣的人,才能創造出「宗教」吧?

滿口熱門的名詞,什麼 lazy 啊、pure 啊、STM 啊,號稱能解決「大規模併發」的問題,…… 這就很容易讓人上鉤。其實他這些詞兒,都是從別的語言道聽途說來,卻又沒能深刻理解其精髓。

有些「函數式語言」的特性,本來就是有問題的,卻為了主義正確,為了顯得高大上,抄過來。所以最後你發現這語言是掛著羊頭賣狗肉,狗皮膏藥一樣說得頭頭是道,用起來怎麼就那麼蹩腳。

Clojure 的社區,一直忙著從 Scheme 和 Racket 的社區抄襲思想,卻又想標榜是自己的發明。比如 Typed Clojure,就是原封不動抄襲 Typed Racket。有些一模一樣的基本概念,在 Scheme 裡面都幾十年了,你是要改個不一樣的名字,免得你們發現那是 Scheme 先有的。

甚至有人把 SICP,The Little Schemer 等名著裡的代碼,全都用 Clojure 改寫一遍,結果完全失去了原作的簡單和清晰。最後你發現,Clojure 裡面好的地方,全都是 Scheme 已經有的,Clojure 裡面新的特性,幾乎全都有問題。我參加過一些 Clojure 的 meetup,可是後來發現,裡面竟是各種喊著大口號的小白,各種趾高氣昂的民間科學家,愚昧之至。

如果現在要做一個系統,真的寧可用 Java,也不要浪費時間去折騰什麼 Scala 或者 Clojure。錯誤的人設計了錯誤的語言,拿出來浪費大家的時間。

  • Java 沒有特別討厭的地方

我至今不明白,很多人對 Java 的仇恨和鄙視,從何而來。它也許缺少一些方便的特性,然而長久以來用 Java 進行教學、用 Java 工作、用 Java 開發 PySonar、RubySonar、Yin 語言,…… 我發現 Java 其實並不像很多人傳說的那麼可惡。我發現自己想要的 95% 以上的功能,在 Java 裡面都能找到比較直接的用法。剩下的 5%,用稍微笨一點的辦法,一樣可以解決問題。

盲目推崇 Scala 和 Clojure 的人們,很多最後都發現,這些語言裡面的「新特性」,幾乎都有毛病,裡面最重要最有用的特性,其實早就已經在 Java 裡了。有些人跟我說:「你看,Java 做不了這件事情!」 後來經我分析,發現他們在潛意識裡早已死板的認定,非得用某種最新最酷的語言特性,才能達到目的。

Java 沒有這些特性,他們就以為非得用另外的語言。其實,如果你換一個角度來看問題,不要鑽牛角尖,專注於解決問題,而不是去追求最新最酷的「寫法」,你就能用 Java 解決它,而且解決得乾淨利落。

很多人說 Java 複雜臃腫,其實是因為早期的Design Patterns,試圖提出千篇一律的模板,給程式帶來了不必要的複雜性。然而 Java 語言本身跟 Design Patterns 並不是等價的。Java 的設計者,跟 Design Pattern 的設計者,完全是不同的人。你完全可以使用 Java 寫出非常簡單的代碼,而不使用 Design Patterns。

Java 只是一個語言。語言只提供給你基本的機制,至於代碼寫的複雜還是簡單,取決於人。把對一些濫用 Design Patterns 的 Java 工程師的恨,轉移到 Java 語言本身,從而完全拋棄它的一切,是不明智的。

  • Java 有優秀的 IDE 支持

我平時都用 IntelliJ 來寫 Java 代碼。我發現 IntelliJ 裡面,有一些非常好的設計思想。其中很多功能,其實超越了所有的文本編輯器(Emacs、VIM……)。IntelliJ 讓 Java 如虎添翼,開發起來感覺是在飛一樣。

用 IntelliJ 的時候,你不需要為「給變量起名字」之類的事情焦慮。因為 IntelliJ 有非常強大而友好的 refactor 功能,你可以非常迅速的換掉變量的名字。所以在第一次創造變量的時候,你不需要花心思去起一個完美的名字。用一個還算湊合的名字,把代碼很快寫出來,實驗成功。然後再返回去看代碼,把名字換成一個更合適的就可以。

IntelliJ 還可以進行非常迅速的結構變換,這讓你就像藝術家在構造一個雕塑作品。最開頭我可以大刀闊斧,把代碼劈成大致的形狀,然後再把它仔細推敲,揉捏成更好,更容易理解,更具魅力的形狀。

工程師這條路,要選,就選個靠譜的語言

我實在不忍心看著有些人被 Scala 和 Clojure 忽悠。如果沒有超級高的性能和資源需求(可能要用 C 這樣的低級語言),目前我建議就老老實實用 Java 吧。雖然不如一些新的語言炫酷,然而實際的系統,還真沒有什麼是 Java 寫不出來的。少數地方可能需要繞過一些限制,或者放寬一些要求,然而這樣的情況不是很多。

寫程式使用什麼工具是重要的,然而工具終究不如自己的技術重要。很多人花了太多時間,折騰各種新的語言,希望它們會奇蹟一般的改善代碼質量,結果最後什麼都沒做出來。選擇語言最重要的條件,應該是「夠好用」就可以,因為項目的成功最終是靠人,而不是靠語言。既然 Java 沒有特別大的問題,不會讓你沒法做好項目,為什麼要去試一些不靠譜的新語言呢?

想學 Java 的話,我幫你整理了一些資源

知名線上 coding 學習網站 Codecademy 也有 Java 的課程區塊。如果英文讓你有點卻步,可以先看一下 Codedata 的中文教材學習,有了基礎後再前往能夠即時顯示結果的 Codecademy 練習。

而如果你遲遲無法決定,曾經在《TO》上刊登的超勵志故事:酒店少爺學 Java、考上大學,也許能夠給你一些前進的力量。

old school 想看書學?沒問題

深入淺出 Java 程式設計

入門首選Java程式設計附範例檔(最新版)

——

(本文獲作者正義的花生授權轉載,原文在此;圖片來源:Sebastiaan ter Burg,CC Licensed。未經授權,不得轉載)

延伸閱讀