淺談java的平臺無關性
(上圖引自《Java經典入門教程》)
事先說明哈,以下僅代表當前個人理解:
說java是平臺無關的語言,我覺得可能會讓人誤解了一些東西,自己之前就一直搞不懂java所謂的平臺無關性是怎樣的或者怎麼實現的。這裡,說一下自己這陣子java學習之後對於這個概念的理解:首先,我認為所謂的語言平臺無關性,其實對於所有高階程式語言(如C/C++、java)來說,都是平臺無關的,因為高階程式語言是用來在人和機器之間搭建更簡便的溝通的方式,或者說更偏向於讓人來理解的,最終無論哪種語言,都是要轉化成0101的機器碼的。這中間有一個很關鍵的步驟,我覺得就是平臺無關性的真正所在,那就是從高階程式語言到0101機器碼中間的轉換,我們知道,高階程式語言需要先編譯轉換成低階程式語言:組合語言,組合語言就是諸如:CPU,來,你給我去把ram裡面的兩段資料A、B拿去相加,然後把相加的結果幫我存回ram的某個地址空間。然後組合語言再經過“彙編階段”把組合語言轉換成0101的機器碼。問題就在於兩層的轉換了,首先,編譯器不同,就可能會導致高階程式語言轉換成機器碼中間兩層就出現不同,比如編譯器a對於一個高階語言做加法(純屬虛構假設):a + b = ?最終會轉換成 100100100但是編譯器b則會將它轉換成 111000111
然後又一個關鍵的問題來了,C/C++編出來的程式往往是直接把可執行檔案,也就是0101的機器碼傳輸給各種機器來跑,那麼我編譯器編譯出來的100100100,機器A能正常識別並正常執行,但是機器B裡面設定的規則是a + b = ? 你只能給我轉換成111000111我才能正常識別並正常執行,現在你給我扔一堆100100100,這樣會咋辦?要麼根本無法執行,要麼CPU流水線執行出來的結果跟預期的截然不同。這樣就帶來了平臺有關性。那麼你就會說了,為什麼CPU廠商和編譯器開發者(這兩者貌似一般是同個公司乾的例如intel)要弄這麼多套規則出來而不是訂一套規範出來大家統一那樣做呢。原因很多,總之現實就是沒這樣做。然後我們會發現一點,對於C/C++這些高階語言來說,語言本身是平臺無關的,它只是方便人們去描述機器要乾的事情。只是最終轉換成機器語言的時候,會產生分支導致不同。好比如說人類要跟動物交流,人類想表達“你今天吃飯了沒”,
拿這個問題去問青蛙,那麼你得跟它說蛙語:哇哇哇,呱呱呱。你再拿這個問題去問小鳥,那麼你得跟它說鳥語:嘰嘰,嘰嘰~。有個大家都期待的解決辦法也一勞永逸的辦法是,咋不讓青蛙和小鳥都學會聽人類的語言呢?那麼我用同樣的一句話,它們就都能聽懂了。但是現實是,不僅動物之間,人類之間,各個國家甚至一個地級市裡面,都有很多種不同的語言。這裡面的原因很複雜,總之現狀就是這樣。既然現狀是如此,那麼java是怎麼解決這個問題的呢?
java運用了一個很樸素的思想,那就是:我是人類,我這麼聰明,幹嘛我非得每次都重複同樣的意思去表達一句話啊,不行,我得開發一個翻譯機,我說人話:你今天吃飯了沒,這機子就會自動幫我轉換,當青蛙來了,這機子就會幫我轉換成蛙語:哇哇哇,呱呱呱。當小鳥又來了,它又會幫我轉換成鳥語:嘰嘰,嘰嘰~對,也就是樹形結構或者說中間層這個思想。一個樹有個根節點,它是圓筒的,然後它有多個分叉,分叉1是方筒的,分叉2是葫蘆狀的,以此類推。然後流水下來了,從根節點的圓筒開始進來,
然後流到了各個分支,不管是方筒的,還是葫蘆狀的還是啥,它們都能幫根節點把這水分流到底層的各個終端。而中間層的思想就是java它幫我們遮蔽了下層的硬體相關性,那就是一個很強大的java虛擬機器,就像一個椅子,我不管它下面是多少個腳或者說它用磚頭還是木頭擺起來的,我只關注一點:讓我坐的是平坦的一個軟墊。java虛擬機器就是這張椅子,它幫我們搞定了下層硬體相關的東西,對你也遮蔽了這些東西,你只需要坐上這個去到哪都一個樣的平坦軟墊,然後在上面寫.java檔案編java程式就行了。那麼問題來了,我個人認為,對java虛擬機器來說,它是硬體相關的,它的設計需要根據實際的硬體情況而定。所以java虛擬機器不是全世界就一個版本,它有多個版本,但是隻要你給你的機器安裝了正確可用的虛擬機器版本,那你上面寫java程式就完全不用擔心硬體相關的東西了。就像我接觸到的java智慧卡,它用的虛擬機器就是定製版本的,虛擬機器地下的作業系統也是定製版本的。你得讓它們去關注硬體相關的東西,去匹配晶片。也就是說,相比於C/C++拿一堆0101的機器碼到處跑,跑到中國有人認識你,但是跑到美國別人就不認識你了。而java它是生成中間程式碼:位元組碼,這個位元組碼是統一的,然後再把這個位元組碼丟給這臺機子上的虛擬機器跑,只要虛擬機器能吻合機器,那我的位元組碼就能跑。所以C/C++能不能我也帶著一份大家都能認識的中間程式碼出去?不好意思,你別改我的C/C++,那是我設計的。所以C#就出來了,C#它是參考了java的。
所以,相比說java是平臺無關語言,我想這句話更不容易讓人陷入困擾:
“Write once, run anywhere.”
編寫一次.java程式,跨平臺執行之。
維基百科對這句話的解釋: