聊聊Java平臺(tái)上的非Java語(yǔ)言
Java 的創(chuàng)造者們?cè)谝婚_始就把Java 語(yǔ)言和Java 虛擬機(jī)分開, 現(xiàn)在看來(lái)是個(gè)非常明智的決定。
Java虛擬機(jī)定義了一個(gè)"軟CPU", 和Intel 的x86 的指令集一樣, 這個(gè)軟CPU也有一套自己的指令,這就意味者對(duì)于任意一門編程語(yǔ)言, 只要你能編譯成Java 的字節(jié)碼指令,或者在運(yùn)行時(shí)動(dòng)態(tài)的生成字節(jié)碼指令, 就可以運(yùn)行在Java虛擬機(jī)中。
Java 虛擬機(jī)發(fā)展了這么多年, 已經(jīng)非常的成熟和穩(wěn)定, 是一個(gè)很有吸引力的平臺(tái)。 除了Java 之外還有不少編程語(yǔ)言慕名而來(lái), 今天就來(lái)聊一聊。
1.Jython和JRuby
從這兩位名字開頭的字母 "J" 就可以看出來(lái)這兩個(gè)語(yǔ)言和Java 的血緣關(guān)系。
沒錯(cuò),他們就是可以運(yùn)行在Java 虛擬機(jī)上的Python 和 Ruby 。 不同于用C語(yǔ)言寫的CPython和 CRuby, 這兩者需要一個(gè)JVM才能運(yùn)行。
既然是運(yùn)行在JVM上的語(yǔ)言, 自然要能調(diào)用Java 類庫(kù), 要不然放著這么多優(yōu)質(zhì)Java 資源不用多可惜!
下面就是一個(gè)在JRuby 腳本中調(diào)用 Java Swing的例子:
如果你思考的深入一些,就會(huì)有這么一個(gè)問題 : 由于Python 和ruby 都是腳本語(yǔ)言, 都是解釋執(zhí)行的, 沒有編譯的過程, 那Jython和JRuby 在解釋的過程中,肯定得生成Java 字節(jié)碼, 要不然JVM就會(huì)把他們拒之門外。那字節(jié)碼是怎么在運(yùn)行中生成的?
答案就是ASM , 一個(gè)可以動(dòng)態(tài)生成字節(jié)碼的Java 類庫(kù)。
(碼農(nóng)翻身注: 參見文章《ASM: 一個(gè)低調(diào)成功者的自述》)
我個(gè)人覺得Jyhton和JRuby能在JVM上運(yùn)行起來(lái),調(diào)用Java 類庫(kù), 是個(gè)很好的賣點(diǎn), 但是卻難以大規(guī)模流行, 原因可能也是類庫(kù)造成的。
最早的時(shí)候?qū)W習(xí)C語(yǔ)言, 由于沒有良好的類庫(kù),就是對(duì)一個(gè)字符串操作都很麻煩, 那些更加高層的語(yǔ)言例如Java, Python, Ruby 就彌補(bǔ)了這個(gè)缺陷, 語(yǔ)言自帶強(qiáng)大的類庫(kù), 再加上社區(qū)的貢獻(xiàn), 用起來(lái)非常順手。 說(shuō)個(gè)題外話, 這也直接導(dǎo)致了很多初學(xué)者的疑問: 語(yǔ)言都封裝好了, 我還學(xué)數(shù)據(jù)結(jié)構(gòu)干嘛?!
Python, Ruby 社區(qū)已經(jīng)積累了大量的、好用的庫(kù), 他們才是Python, Ruby一派繁榮的主要原因, 但是這些庫(kù)都是Python, Ruby寫的, 也有不少是C語(yǔ)言寫的, 這些海量的類庫(kù)全部移植到Java 上絕非易事, 我們也不能要求類庫(kù)的作者同時(shí)提供Java 版本 。
而Java 現(xiàn)成的類庫(kù)總是感覺和Python , Ruby 有一點(diǎn)Gap, 語(yǔ)言設(shè)計(jì)的思維不同, 雖然可以集成互操作, 但還是感覺別扭。
也許Jython和JRbuy 只是小范圍內(nèi)或者特定場(chǎng)合使用吧。
2.Groovy
Groovy 并不像Jython, JRuby, 它并不是一個(gè)現(xiàn)有語(yǔ)言在JVM上的移植, 而是一個(gè)全新設(shè)計(jì)的語(yǔ)言。
Groovy被定義為JVM上的動(dòng)態(tài)腳本語(yǔ)言, 適合編寫腳本, 測(cè)試用例和 領(lǐng)域特定語(yǔ)言(DSL)。
用Groovy 寫的軟件中有兩個(gè)比較知名:
1). Gradle
一個(gè)風(fēng)頭正勁的Build 工具, 得益于Groovy 簡(jiǎn)潔的語(yǔ)法, 可以用“Build領(lǐng)域特定的語(yǔ)言”來(lái)描述一個(gè)軟件的構(gòu)建過程, 寫出的Build腳本 和Ant, Maven 的xml 腳本 相比,讀起來(lái)更賞心悅目。 在Web項(xiàng)目,Android項(xiàng)目的 Build過程中有大量使用。
下面是一個(gè)例子, 大家可以感受一下和Maven 的區(qū)別:
2). Grail
這應(yīng)該是模仿Ruby on Rail的一個(gè)項(xiàng)目,熱度已經(jīng)過去, 估計(jì)使用的人不多了。
記得在2008年IBM的毛新生帶領(lǐng)著團(tuán)隊(duì)搞了一個(gè)Project Zero出來(lái), 基于Groovy和PHP, 目標(biāo)是快速Web項(xiàng)目開發(fā), 喧囂了一陣也是歸于沉寂。
在JVM上, Java 是毋庸置疑的老大, Spring 是一座難以撼動(dòng)的大山, 所以Groovy ***還是把注意力集中到 小工具,測(cè)試 以及Build上, 這是它能***發(fā)揮能量的地方。
3.Scala 和 Clojure
Scala ***次進(jìn)入我的視線是一則新聞: Twitter 決定把核心應(yīng)用從Ruby on Rails 遷移到Scala,作為曾經(jīng)的Ruby擁躉, 看到這個(gè)消息是讓人沮喪的 : Twitter 可是Ruby on Rails 經(jīng)常拿來(lái)宣傳的一個(gè)明星系統(tǒng)了, 現(xiàn)在Twitter 竟然想轉(zhuǎn)到Scala , Scala是什么鬼? 怎么可能獲得Twitter 工程師的青睞?
后來(lái)看了一下,Scala是一個(gè)很有趣的語(yǔ)言, 在他的官網(wǎng)上寫著“Object-Oriented Meets Functional” , 面向?qū)ο笥錾狭撕瘮?shù)式編程 ! 也就是說(shuō)一門語(yǔ)言混合了兩種編程范型。 不僅如此,它還是一個(gè)可以運(yùn)行在Java 虛擬機(jī)上的語(yǔ)言, JVM的成熟和穩(wěn)定, 可能也是Twitter 工程師選擇Scala的重要原因。
(碼農(nóng)翻身注: 關(guān)于函數(shù)式編程, 可以參考《命令式編程 vs 聲明式編程》)
有人說(shuō)了,我面向?qū)ο筮€沒學(xué)完呢, 還學(xué)函數(shù)式編程? 我推薦你看看《黑客與畫家》一書, 看完以后十有八九會(huì)被Paual 自身成功的案例和 富有煽動(dòng)性的語(yǔ)言給鼓動(dòng)起來(lái), 熱血沸騰的去嘗試函數(shù)式編程語(yǔ)言Lisp(我就是如此) :-)
但是我相信大部分人都只是淺嘗輒止, 因?yàn)榧兒瘮?shù)式編程和我們?nèi)粘J褂玫腃, Java, Python 這些命令式編程語(yǔ)言大相徑庭, 需要巨大的思維轉(zhuǎn)變, ***是完全忘掉之前所學(xué)的命令式編程才行, 所以學(xué)習(xí)曲線極為陡峭, 把很多人都嚇回去了。
現(xiàn)在好了, Scala即支持OO, 又支持Functional , 你可以在一個(gè)相對(duì)舒服的環(huán)境漸漸的去嘗試函數(shù)式編程的奧妙,確實(shí)是不錯(cuò)的選擇。
如果你非要學(xué)習(xí)一個(gè)純粹的函數(shù)式編程語(yǔ)言, 可以考慮Clojure ,這是一個(gè)運(yùn)行在JVM中的lisp方言, 同樣可以和Java 類庫(kù)互操作。
4.總結(jié)
說(shuō)了這么多, 如果讓我為一個(gè)大型項(xiàng)目選擇語(yǔ)言, 我極有可能還是要選擇Java, 對(duì)于一個(gè)大型項(xiàng)目來(lái)說(shuō), 代碼的可讀性、可維護(hù)性是非常重要的,我之前讀一些動(dòng)態(tài)語(yǔ)言的代碼, 看到一個(gè)變量而不知道它的類型,沒法查看它的行為, 這是非常令人抓狂的體驗(yàn)。
而Java 這種靜態(tài)類型的語(yǔ)言,IDE的感知能力, 安全重構(gòu)的能力是極為重要的, 讓人覺得安全,可控,適合大團(tuán)隊(duì)協(xié)作。
【本文為51CTO專欄作者“劉欣”的原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)通過作者微信公眾號(hào)coderising獲取授權(quán)】