1. 程式人生 > 實用技巧 >Java相關知識

Java相關知識

Java特性和優勢

  • 簡單性
  • 面向物件
  • 可移植性(Write Once,Run Anywhere)
  • 高效能
  • 分散式
  • 動態性(反射機制)
  • 多執行緒
  • 安全性
  • 健壯性

Java三大版本

  • Java SE:標準版(桌面程式,控制檯開發......)
  • Java ME:嵌入式開發 (手機,小家電......已經涼了)
  • Java SE:企業級開發(web端,伺服器開發......)

JDK,JRE,JVM

JDK(Java Development Kit)

是整個JAVA的核心,包括了Java執行環境(jre),一堆Java工具(javac/java/jdb等)和Java基礎的類庫(即Java API 包括rt.jar)。

JDK是java開發工具包,基本上每個學java的人都會先在機器 上裝一個JDK,那他都包含哪幾部分呢?在目錄下面有 六個資料夾、一個src類庫原始碼壓縮包、和其他幾個宣告檔案。其中,真正在執行java時起作用的 是以下四個資料夾:bin、include、lib、 jre。有這樣一個關係,JDK包含JRE,而JRE包 含JVM。

# bin :最主要的是編譯器(javac.exe)
# include: java和JVM互動用的標頭檔案
# lib: 類庫
# jre:java執行環境 

(注意:這裡的bin、lib資料夾和jre裡的bin、lib是 不同的)

總的來說JDK是用於java程式的開發,而jre則是隻能執行class而沒有編譯的功能。

JRE(Java Runtime Environment )

JRE(Java Runtime Environment,Java執行環境),包含JVM標準實現及Java核心類庫。JRE是Java執行環境,並不是一個開發環境,所以沒有包含任何開發工具(如編譯器和偵錯程式)

JRE是指java執行環境。光有JVM還不能完成class的 執行,因為在解釋class的時候JVM需要呼叫解釋所需要的類庫lib。 (jre裡有執行.class的java.exe)

JRE ( Java Runtime Environment ),是執行 Java 程式必不可少的(除非用其他一些編譯環境編譯成.exe可執行檔案……),JRE的 地位就象一臺PC機一樣,我們寫好的Win64應用程式需要作業系統幫 我們執行,同樣的,我們編寫的Java程式也必須要JRE才能執行。

JVM(Java Virtual Machine)

JVM(Java Virtual Machine),即java虛擬機器, java執行時的環境,JVM是一種用於計算裝置的規範,它是一個虛構出來的計算機,是通過在實際的計算機上模擬模擬各種計算機功能來實現的。針對java使用者,也就是擁有可執行的.class檔案包(jar或者war)的使用者。裡面主要包含了jvm和java執行時基本類庫(rt.jar)。rt.jar可以簡單粗暴地理解為:它就是java原始碼編譯成的jar包。

Java虛擬機器在執行位元組碼時,把位元組碼解釋成具體平臺上的機器指令執行。這就是Java的能夠“一次編譯,到處執行”的原因。

三者聯絡

JVM不能單獨搞定class的執行,解釋class的時候JVM需要呼叫解釋所需要的類庫lib。在JDK下面的的jre目錄裡面有兩個資料夾bin和lib,在這裡可以認為bin裡的就是jvm,lib中則是jvm工作所需要的類庫,而jvm和 lib和起來就稱為jre。JVM+Lib=JRE。總體來說就是,我們利用JDK(呼叫JAVA API)開發了屬於我們自己的JAVA程式後,通過JDK中的編譯程式(javac)將我們的文字java檔案編譯成JAVA位元組碼,在JRE上執行這些JAVA位元組碼,JVM解析這些位元組碼,對映到CPU指令集或OS的系統呼叫。

三者區別

JDK和JRE區別:在bin資料夾下會發現,JDK有javac.exe而JRE裡面沒有,javac指令是用來將java檔案編譯成class檔案的,這是開發者需要的,而使用者(只需要執行的人)是不需要的。JDK還有jar.exe, javadoc.exe等等用於開發的可執行指令檔案。這也證實了一個是開發環境,一個是執行環境。

JRE和JVM區別:JVM並不代表就可以執行class了,JVM執行.class還需要JRE下的lib類庫的支援,尤其是rt.jar。

Java程式執行機制

編譯型

對於編譯型語言,開發完成後需要將所有的原始碼都轉換成可執行程式,比如window下的exe檔案,可執行程式裡面包含的就是機器碼。只要我們擁有可執行程式,就可以隨時執行,不用再重新編譯,也就是“一次編譯,無限次執行”

在執行時,我們只需要編譯生成的可執行程式,不在需要原始碼和編譯器了,所以說編譯型語言可以脫離開發環境執行

編譯型語言一般是不能跨平臺的,也就是不能在不同的作業系統之間隨意切換

不能跨平臺表現在兩個方面

  1. 可執行程式不能跨平臺

    這個很好理解,不再贅述

  2. 原始碼不能跨平臺
    不同平臺支援的函式,型別,變數等都可能不同。例如c語言的睡眠函式,在windows平臺下該函式是 Sleep(),在 Linux 平臺下該函式是 sleep(),首字母大小寫不同。其次,Sleep() 的引數是毫秒,sleep() 的引數是秒,單位也不一樣。

    雖然不同平臺的C語言都支援 long 型別,但是不同平臺的 long 的長度卻不同,例如,Windows 64 位平臺下的 long 佔用 4 個位元組,Linux 64 位平臺下的 long 佔用 8 個位元組。
    我們在 Linux 64 位平臺下編寫程式碼時,將 0x2f1e4ad23 賦值給 long 型別的變數是完全沒有問題的,但是這樣的賦值在 Windows 平臺下就會導致數值溢位,讓程式產生錯誤的執行結果。

解釋型

對於解釋型語言,每次執行程式都需要一邊轉換一邊執行,用到哪些原始碼就將哪些原始碼轉換成機器碼,用不到的不進行任何處理。每次執行程式時可能使用不同的功能,這個時候需要轉換的原始碼也不一樣。

因為每次執行程式都需要重新轉換原始碼,所以解釋型語言的執行效率天生就低於編譯型語言,甚至存在數量級的差距。計算機的一些底層功能,或者關鍵演算法,一般都使用 C/C++ 實現,只有在應用層面(比如網站開發、批處理、小工具等)才會使用解釋型語言。

在執行解釋型語言的時候,我們始終都需要原始碼和直譯器,所以說它無法脫離開發環境。

當我們說“下載一個程式(軟體)”時,不同型別的語言有不同的含義:

  • 對於編譯型語言,我們下載到的是可執行檔案,原始碼被作者保留,所以編譯型語言的程式一般是閉源的。
  • 對於解釋型語言,我們下載到的是所有的原始碼,因為作者不給原始碼就沒法執行,所以解釋型語言的程式一般是開源的。

相比於編譯型語言,解釋型語言幾乎都能跨平臺,“一次編寫,到處執行”是真是存在的,而且比比皆是

解釋型語言能跨平臺主要靠直譯器

我們所說的跨平臺,是指原始碼跨平臺,而不是直譯器跨平臺。直譯器用來將原始碼轉換成機器碼,它就是一個可執行程式,是絕對不能跨平臺的

官方需要針對不同的平臺開發不同的直譯器,這些直譯器必須要能夠遵守同樣的語法,識別同樣的函式,完成同樣的功能,只有這樣,同樣的程式碼在不同平臺的執行結果才是相同的。

解釋型語言之所以能夠跨平臺,是因為有了直譯器這個中間層。在不同的平臺下,直譯器會將相同的原始碼轉換成不同的機器碼,直譯器幫助我們遮蔽了不同平臺之間的差異

Java和C#是比較奇葩的存在,它們是半編譯半解釋型的語言,原始碼需要先轉換成一種中間檔案(位元組碼檔案),然後再將中間檔案拿到虛擬機器中執行。Java 引領了這種風潮,它的初衷是在跨平臺的同時兼顧執行效率;C# 是後來的跟隨者,但是 C# 一直止步於 Windows 平臺,在其它平臺鮮有作為。