Knowledge Point 20180506 深究Java的跨平臺特性

  本章主題:從骨子裏看Java的跨平臺;本文內容部分摘自http://www.javashuo.com/article/p-nloylylr-ha.htmlhtml

  有過基礎Java知識的開發人員都知道Java是跨平臺的,可咱們知道Java爲何要跨平臺嗎,Java的跨平臺又是如何實現的呢?下面咱們來一一瞭解。java

1.什麼是平臺

  Java是能夠跨平臺的編程語言,那咱們首先得知道什麼是平臺,Java是一個高級開發語言,經過操做系統提供的接口進行開發,因此這裏的平臺主要指的就是操做系統了。linux

  操做系統是充當用戶和計算機之間交互的界面軟件,不一樣的操做系統支持不一樣的CPU,嚴格意義上說是不一樣的操做系統支持不一樣CPU的指令集。例如  windowsliunx都支持IntelAMD的複雜指令集,但並不支持PowerPC所使用的精簡指令集,而早期的MAC電腦使用的是PowerPC處理器,因此也就沒法在MAC下直接安裝windows,直到05MAC改用了IntelCPU,才使在MAC下安裝windows成爲可能。但問題來了,原來的MAC 操做系統也只支持PowerPC,Intel上也不能安裝,怎麼辦?因此蘋果公司也得重寫本身的MAC操做系統以支持這種變化。最後總結下,咱們要知道,不一樣的操做系統支持不一樣的CPU指令集,如今的windows,liunx,mac,solaris都支持IntelAMDCPU指令集。程序員

  有了上面的鋪墊,下面就要告訴你們,若是您要開發程序,首先應該肯定本身使用什麼操做系統,知道什麼是平臺,咱們看Java跨平臺原理。web

2.Java跨平臺的原理

  首先看一張與C語言有關的圖:   編程

 

  若是您有過C的開發經歷,這張圖看起來將很是輕鬆。咱們知道,只要是用標準C開發的程序,使用不一樣的編譯器【編譯器:將一種語言規範轉化爲另外一種語言規範,一般編譯器是將便於人們理解的語言規範轉化爲機器容易理解的語言規範。例如,咱們將C語言的語言規範轉換爲平臺的語言規範(可以被平臺識別的指令集),這是C語言編譯器所作的事情】編譯後的可執行文件是能夠在對應平臺運行的,好比windows可使用VC編譯,那編譯後的exe文件就能夠在windows下運行;liunx下可使用GCC編譯,生成的可執行文件就能夠在Liunx上運行。到這裏請你們思考一個問題:「VC編譯的exe能在Liunx上運行嗎?windows

  答案確定是否認的。使用特定編譯器編譯的程序只能在對應的平臺運行,這裏也能夠說編譯器是與平臺相關的,編譯後的文件是與平臺相關的。咱們說的語言跨平臺是編譯的文件跨平臺【跨平臺分爲源碼級的跨平臺和中間碼的跨平臺】,而不是源程序跨平臺,若是是源程序,任何一門語言都是跨平臺的語言了。這個若是您不明白,看下面一個案例:好比火星真的有外星人(而且毋庸置疑,火星是韓國人的,火星文也必定是韓國人發明的),就像咱們觀察螞蟻同樣,火星人默默的觀察着咱們,有一天,當人類作的 什麼事情讓火星人實在是看不下去了(好比你的單純趕上可惡的拜金),因此決定來地球教育咱們,但有一個問 題,火星人只會說火星文,地球人理解不了,怎麼辦啊?找翻譯唄(也許非主流能夠幫忙,玩笑)!由中文翻譯把火星文翻譯爲中文,英文翻譯把火星文翻譯爲英文 等等等等,但這樣問題來了,中文翻譯翻譯的東西只有中國人能聽懂,美國人法國人根本不明白,英文翻譯翻譯的文章中國人也不明白,也就是語言不能跨平臺。瀏覽器

  那上例中,火星文就是C語言,各個國家是平臺,中文翻譯英文翻譯就是對應平臺的編譯器,編譯後的文章就是可執行文件。雖然源文章火星文是與平臺無關的,但翻譯器是與特定國家相關的,翻譯後的文章也是與特定國家相關的。接下來思考另外一個問題怎麼讓火星文跨平臺呢?安全

  火星人想到了地球上有世界語,因而首先把本身的文章翻譯爲世界語;世界語各國人固然看不懂,不要緊,火星人又給每一個國家配備了一個世界語到本地語的翻譯,這 樣火星文只要翻譯一次(翻譯爲世界語),就能夠到各個國家運行了。還要記住,這個過程火星人要提供兩個組件,第一是火星文到世界語的翻譯,第二是世界語到對應本地語言的翻譯。以下圖:服務器

 

  有了上面案例的積累,咱們也知道了語言跨平臺原理:不能編譯成機器語言,由於那樣就與平臺相關了,編譯爲中間語言,再由解釋器二次編譯,解釋執行。以下是Java跨平臺原理表示圖:

 

  上圖中的.java就是源程序,相似於c語言的.c,生成的中間碼是.class,這個既是咱們上文中說的中間語,各個平臺解釋器就是各類國家翻譯。

接下來咱們再比較下兩種方式的差別:

  • 第一,C語言是編譯執行的,編譯器與平臺相關,編譯生成的可執行文件與平臺相關
  • 第二,Java是解釋執行的,編譯爲中間碼的編譯器與平臺無關,編譯生成的中間碼也與平臺無關(一次編譯,處處運行),中間碼再由解釋器解釋執行,解釋器是與平臺相關的,也就是不一樣的平臺須要不一樣的解釋器.

這裏再說下語言根據執行方式的不一樣分類:

  • 第一是編譯執行,如上文中說到的C,它把源程序由特定平臺的編譯器一次性編譯爲平臺相關的機器碼,它的優勢是執行速度快,缺點是沒法跨平臺;
  • 第二是解釋執行,如HTML,JavaScript,它使用特定的解釋器,把代碼一行行解釋爲機器碼,相似於同聲翻譯,它的優勢是能夠跨平臺,缺點是執行速度慢,暴露源程序;
  • 第三種是從Java開始引入的中間碼+虛擬機的方式,它既整合了編譯語言與解釋語言的優勢,同時如虛擬機又能夠解決如垃圾回收,安全性檢查等這些傳統語言頭疼的問題,因此其後微軟的.NET平臺也使用的這種方式。

3.跨平臺的優勢

  從上面咱們知道了Java跨平臺的原理即最後生成的由平臺操做的程序文件對於不一樣的平臺是不一樣的,Java源文件通過編譯生成字節碼文件.class,字節碼文件經由JVM解釋生成能被平臺執行的機器語言;在這個過程當中咱們注意字節碼文件是相同的,不一樣的是通過解釋後的機器碼,Java跨平臺正是基於解釋.class文件的虛擬機的,可是虛擬機倒是不跨平臺的,只要在須要運行java應用程序的操做系統上,先安裝一個Java虛擬機(JVM JavaVirtual Machine)便可。由JVM來負責Java程序在該系統中的運行。簡單來講就是如圖所示那樣程序代碼通過編譯以後轉換爲一種稱爲Java字節碼的中間語言,Java虛擬機(JVM)將對字節碼進行解釋和運行。編譯只進行一次,而解釋在每次運行程序時都會進行。編譯後的字節碼採用一種針對JVM優化過的機器碼形式保存,虛擬機將字節碼解釋爲機器碼,而後在計算機上面運行。

  同一個.class文件在不一樣的虛擬機會獲得不一樣的機器指令(WindowsLinux的機器指令不一樣),可是最終執行的結果倒是相同的

  跨平臺使得Java的源代碼一經編譯能夠藉助於JVM處處運行實現了它的「write once,run anywhere」可是隨着JavaB/S中的普遍使用,跨平臺的特性顯得就有些雞肋了,這是由於B/S咱們藉助瀏覽器對網絡另外一端的服務器訪問,此時相對應的客戶端只是依賴與瀏覽器,因此平臺相對應的只是服務器的平臺,因此從客戶端來看它的跨平臺就很"雞肋",實際上這種想法是很偏見的.下面咱們來聊一下Java跨平臺的雞肋.

4.聊聊"雞肋"Java跨平臺

  咱們初學Java,只怕最深的印象就在於Java的跨平臺了,咱們的前輩教師,老是會將Java的跨平臺誇讚的不得了,可實際接觸開發一段時間後,會不會有這麼一個疑問呢?那就是Java源自於C++,C++是如何操做的呢?Java的跨平臺究竟在C++的基礎上,作出了哪些進步呢?爲何網上有了一種說法,Java的跨平臺很"雞肋"?是這樣嗎?下邊針對這些問題聊聊;

    C++語言原本就是跨平臺的,不過是「源碼級」跨平臺。原本就存在針對linuxwindows的不一樣的編譯器。因此有C語言「一次編寫,處處編譯」,Java是「一次編譯,處處運行」的說法。如C++創始人酸溜溜的說法,JVM造了一個新的平臺,讓全部Java程序只能在這個平臺上運行,而CC++的代碼能夠在幾十個不一樣的平臺上運行,從源碼這個角度而言,CC++是跨平臺的,而Java不是。這裏所說的源碼是通過編寫不曾編譯的。那麼這麼看起來Java的跨平臺是否是真的有些雞肋了呢?

  這種說法也是有失偏頗的,由於JavaC針對的方向不一樣因此跨平臺承擔的責任也就不一樣了,C主要用於系統底層的開發,如操做系統Linux,硬件驅動程序。因此對於跨平臺就是源碼級別的。而Java呢則屬於中間碼的跨平臺。

  C++ 編譯生成的是純二進制的機器指令,而JAVA編譯生成的是非純二進制的字節碼。而這種基於Unicode的字節碼是不依賴於特定的計算機硬件架構而存在的——這就意味着只要有JVM環境,你的字節碼就能夠在任何平臺上運行。其次,JAVA字節碼的二進制數據以固定的格式進行存儲和傳輸,消除了字節順序的干擾。

  JAVA爲何能跨平臺?由於字節碼是在虛擬機上運行的,而不是編譯器。換而言之,是由於JVM能跨平臺安裝,因此相應JAVA字節碼即可以跟着在任何平臺上運行。只要JVM自身的代碼能在相應平臺上運行,即JVM可行,則JAVA的程序員就能夠不用考慮所寫的程序要在哪裏運行,反正都是在虛擬機上運行,而後變成相應平臺的機器語言,而這個轉變並非程序員應該關心的。

       Java的起源, 發明的初衷, 最開始Java是爲了單片機開發的, 而單片機的發展是很迅速的, 你花了半年爲某種單片機開發了程序, 等程序出來了可能這個型號的單片機已經沒人用了, Sun當時是爲了解決這個問題, 提出了程序只用寫一遍編譯一遍, 而後讓JVM來適應單片機型號的不一樣.這是最初的跨平臺,而發展到了今天呢?咱們知道Java已經成爲了web開發的主流語言,但是咱們開發的時候是在Windows下開發,而部署每每是部署在LinuxUnix下的,因此此時Java的跨平臺就又能夠大展神威了,由於無論何時,Java說白了都是運行在JVM上的,真正須要跨平臺的是JVM,因此對於咱們編寫程序來講,就讓編碼和跨平臺分開了,便利了開發和測試。最爲引人注意的一點是,Java在繼承C++的優勢的時候,也摒棄了C++的缺點,其中有一點就是內存的分配和回收,Java將這部分工做交由JVM自動執行,而減輕了開發人員對於這方面的操做,因此說Java的跨平臺是不少因素形成的,發展到了今天Java已經超出了一種語言,更多的成爲了一個平臺。【想象一下若是是如C++那樣的編寫方法,那麼咱們編寫後的程序部署後還要再通過編譯才能夠,而經過Java咱們能夠在開發中直接編譯,只須要將中間碼部署在服務器上,其後的事情就不須要咱們來管理了,相對來講開發和部署就簡單了。】

  咱們做爲編寫端,只注重在編寫代碼,至於跨平臺的任務就交給了JVM來處理,中間碼是跨平臺的,JVM卻不是跨平臺的,這點要注意!

  綜上;咱們說Java的跨平臺雞肋,是很片面的,針對性不一樣,沒有可比性!

贅述

  咱們有沒有考慮這麼一個問題,那就是一樣跨平臺,爲何互聯網開發更多的選擇了Java,而沒有選擇C呢?

  其實選擇哪一種語言用於開發,這並無一個徹底正確的答案,咱們使用Java開發的程序,一樣也是可使用C開發的,只不過,在互聯網發展之初對於語言的要求就是安全,跨平臺和支持互聯網操做,而Java很好的支持了這些,同時Java源於C++,又摒棄了C++中的很差的東西,因此相對來講Java的簡單受到了更多人的推崇,使用的人多了,市場上對其的支持也就多了。

相關文章
相關標籤/搜索