1. 程式人生 > >Question20180105 Java的跨平臺特性的原理

Question20180105 Java的跨平臺特性的原理

宋體 machine 一行 註意 垃圾 真的 引入 是否 unix

Java的 跨平臺特性和為什麽Java要擁有這個特性

註:相關內容摘自網絡,忘記出處,故未註明,若有不妥忘其告知,加以改正;

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

1.什麽是平臺

  Java是可以跨平臺的編程語言,那我們首先得知道什麽是平臺,Java是一個高級開發語言,通過操作系統提供的接口進行開發,所以這裏的平臺指的就是操作系統了

  操作系統是充當用戶和計算機之間交互的界面軟件,不同的操作系統支持不同的CPU,嚴格意義上說是不同的操作系統支持不同CPU的指令集。例如

windowsliunx都支持IntelAMD的復雜指令集,但並不支持PowerPC所使用的精簡指令集,而早期的MAC電腦使用的是PowerPC處理器,所以也就無法在MAC下直接安裝windows,直到05MAC改用了IntelCPU,才使在MAC下安裝windows成為可能。但問題來了,原來的MAC 操作系統也只支持PowerPC,Intel上也不能安裝,怎麽辦?所以蘋果公司也得重寫自己的MAC操作系統以支持這種變化。最後總結下,我們要知道,不同的操作系統支持不同的CPU指令集,現在的windows,liunx,mac,solaris都支持IntelAMDCPU指令集。

  有了上面的鋪墊,

下面就要告訴大家,如果您要開發程序,首先應該確定自己使用得什麽操作系統,知道什麽是平臺,我們看Java跨平臺原理。

2.Java跨平臺的原理

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

技術分享圖片

  如果您有過C的開發經歷,這張圖看起來將非常輕松。我們知道,只要是用標準C開發的程序,使用不同的編譯器【編譯器:將一種語言規範轉化為另一種語言規範,通常編譯器是將便於人們理解的語言規範轉化為機器容易理解的語言規範。例如,我們將C語言的語言規範轉換為平臺的語言規範(能夠被平臺識別的指令集),這是C語言編譯器所做的事情】編譯後的可執行文件是可以在對應平臺運行的,比如windows可以使用VC編譯,那編譯後的exe

文件就可以在windows下運行;liunx下可以使用GCC編譯,生成的可執行文件就可以在Liunx上運行。到這裏請大家思考一個問題:“VC編譯的exe能在Liunx上運行嗎?

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

  那上例中,火星文就是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優化過的機器碼形式保存,虛擬機將字節碼解釋為機器碼,然後在計算機上面運行。

  Java先編譯後解釋

  同一個.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語言本來就是跨平臺的,不過是“源碼級”跨平臺。本來就存在針對linux、windows的不同的編譯器。所以有C語言“一次編寫,到處編譯”,Java是“一次編譯,到處運行”的說法。如C++創始人酸溜溜的說法,JVM造了一個新的平臺,讓所有Java程序只能在這個平臺上運行,而C和C++的代碼可以在幾十個不同的平臺上運行,從源碼這個角度而言,C和C++是跨平臺的,而Java不是。這裏所說的源碼是經過編寫未曾編譯的。那麽這麽看起來Java的跨平臺是不是真的有些雞肋了呢?

  這種說法也是有失偏頗的,因為Java和C針對的方向不同所以跨平臺承擔的責任也就不同了,C主要用於系統底層的開發,如操作系統:Linux,硬件驅動程序。所以對於跨平臺就是源碼級別的。而Java呢?

Java的起源, 發明的初衷, 最開始Java是為了機頂盒開發的, 機頂盒用的CPU不是x86架構的intel CPU而是單片機, 而單片機的發展是很迅速的, 你花了半年為某種單片機開發了程序, 等程序出來了可能這個型號的單片機已經沒人用了, Sun當時是為了解決這個問題, 提出了程序只用寫一遍編譯一遍, 然後讓JVM來適應單片機型號的不同.這是最初的跨平臺,而發展到了今天呢?我們知道Java已經成為了web開發的主流語言,可是我們開發的時候是在Windows下開發,而部署往往是部署在Linux和Unix下的,所以此時Java的跨平臺就又可以大展神威了,因為不管什麽時候,Java說白了都是運行在JVM上的,真正需要跨平臺的是JVM,所以對於我們編寫程序來說,就讓編碼和跨平臺分開了,便利了開發。

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

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

Question20180105 Java的跨平臺特性的原理