總結(jié)一下java核心技術(shù)36講的第一講,做做筆記
從你接觸 Java 開(kāi)發(fā)到現(xiàn)在,你對(duì) Java 最直觀的印象是什么呢仑鸥?是它宣傳的 “Write once, run anywhere”吮播,還是目前看已經(jīng)有些過(guò)于形式主義的語(yǔ)法呢?你對(duì)于 Java 平臺(tái)到底了解到什么程度眼俊?請(qǐng)你先停下來(lái)總結(jié)思考一下。
今天我要問(wèn)你的問(wèn)題是粟关,談?wù)勀銓?duì) Java 平臺(tái)的理解疮胖?“Java 是解釋執(zhí)行”,這句話正確嗎闷板?
Java 本身是一種面向?qū)ο蟮恼Z(yǔ)言澎灸,最顯著的特性有兩個(gè)方面,一是所謂的“書(shū)寫(xiě)一次遮晚,到處運(yùn)行”(Write once, run anywhere)性昭,能夠非常容易地獲得跨平臺(tái)能力;另外就是垃圾收集(GC, Garbage Collection)县遣,Java 通過(guò)垃圾收集器(Garbage Collector)回收分配內(nèi)存糜颠,大部分情況下,程序員不需要自己操心內(nèi)存的分配和回收萧求。
我們?nèi)粘?huì)接觸到 JRE(Java Runtime Environment)或者 JDK(Java Development Kit)其兴。 JRE,也就是 Java 運(yùn)行環(huán)境夸政,包含了 JVM 和 Java 類庫(kù)元旬,以及一些模塊等。而 JDK 可以看作是 JRE 的一個(gè)超集,提供了更多工具匀归,比如編譯器坑资、各種診斷工具等。
一次編譯穆端、到處運(yùn)行”說(shuō)的是Java語(yǔ)言跨平臺(tái)的特性袱贮,Java的跨平臺(tái)特性與Java虛擬機(jī)的存在密不可分,可在不同的環(huán)境中運(yùn)行徙赢。比如說(shuō)Windows平臺(tái)和Linux平臺(tái)都有相應(yīng)的JDK字柠,安裝好JDK后也就有了Java語(yǔ)言的運(yùn)行環(huán)境。其實(shí)Java語(yǔ)言本身與其他的編程語(yǔ)言沒(méi)有特別大的差異狡赐,并不是說(shuō)Java語(yǔ)言可以跨平臺(tái)窑业,而是在不同的平臺(tái)都有可以讓Java語(yǔ)言運(yùn)行的環(huán)境而已,所以才有了Java一次編譯枕屉,到處運(yùn)行這樣的效果常柄。
嚴(yán)格的講,跨平臺(tái)的語(yǔ)言不止Java一種搀擂,但Java是較為成熟的一種西潘。“一次編譯哨颂,到處運(yùn)行”這種效果跟編譯器有關(guān)喷市。編程語(yǔ)言的處理需要編譯器和解釋器。Java虛擬機(jī)和DOS類似威恼,相當(dāng)于一個(gè)供程序運(yùn)行的平臺(tái)品姓。
程序從源代碼到運(yùn)行的三個(gè)階段:編碼——編譯——運(yùn)行——調(diào)試。Java在編譯階段則體現(xiàn)了跨平臺(tái)的特點(diǎn)箫措。編譯過(guò)程大概是這樣的:首先是將Java源代碼轉(zhuǎn)化成.CLASS文件字節(jié)碼腹备,這是第一次編譯。.class文件就是可以到處運(yùn)行的文件斤蔓。然后Java字節(jié)碼會(huì)被轉(zhuǎn)化為目標(biāo)機(jī)器代碼植酥,這是是由JVM來(lái)執(zhí)行的,即Java的第二次編譯弦牡。
“到處運(yùn)行”的關(guān)鍵和前提就是JVM友驮。因?yàn)樵诘诙尉幾g中JVM起著關(guān)鍵作用。在可以運(yùn)行Java虛擬機(jī)的地方都內(nèi)含著一個(gè)JVM操作系統(tǒng)喇伯。從而使JAVA提供了各種不同平臺(tái)上的虛擬機(jī)制喊儡,因此實(shí)現(xiàn)了“到處運(yùn)行”的效果。需要強(qiáng)調(diào)的一點(diǎn)是稻据,java并不是編譯機(jī)制艾猜,而是解釋機(jī)制买喧。Java字節(jié)碼的設(shè)計(jì)充分考慮了JIT這一即時(shí)編譯方式,可以將字節(jié)碼直接轉(zhuǎn)化成高性能的本地機(jī)器碼匆赃,這同樣是虛擬機(jī)的一個(gè)構(gòu)成部分淤毛。
Java語(yǔ)言具有跨平臺(tái)的特性,也正是因?yàn)樘摂M機(jī)的存在算柳。Java源文件被編譯成字節(jié)碼低淡,被虛擬機(jī)加載后執(zhí)行。這里隱含的意思有兩層:
1)大部分情況下瞬项,編程者只需要關(guān)心Java語(yǔ)言本身蔗蹋,而無(wú)需特意關(guān)心底層細(xì)節(jié)。包括對(duì)內(nèi)存的分配和回收囱淋,也全權(quán)交給了GC猪杭。
2)對(duì)于虛擬機(jī)而言,只要是符合規(guī)范的字節(jié)碼妥衣,它們都能被加載執(zhí)行皂吮,當(dāng)然,能正常運(yùn)行的程序光滿足這點(diǎn)是不行的税手,程序本身需要保證在運(yùn)行時(shí)不出現(xiàn)異常蜂筹。所以,Scala芦倒、Kotlin艺挪、Jython等語(yǔ)言也可以跑在虛擬機(jī)上。
對(duì)于“Java 是解釋執(zhí)行”這句話兵扬,這個(gè)說(shuō)法不太準(zhǔn)確闺属。我們開(kāi)發(fā)的 Java 的源代碼,首先通過(guò) Javac 編譯成為字節(jié)碼(bytecode)周霉,然后,在運(yùn)行時(shí)亚皂,通過(guò) Java 虛擬機(jī)(JVM)內(nèi)嵌的解釋器將字節(jié)碼轉(zhuǎn)換成為最終的機(jī)器碼俱箱。但是常見(jiàn)的 JVM,比如我們大多數(shù)情況使用的 Oracle JDK 提供的 Hotspot JVM灭必,都提供了 JIT(Just-In-Time)編譯器狞谱,也就是通常所說(shuō)的動(dòng)態(tài)編譯器,JIT 能夠在運(yùn)行時(shí)將熱點(diǎn)代碼編譯成機(jī)器碼禁漓,這種情況下部分熱點(diǎn)代碼就屬于編譯執(zhí)行跟衅,而不是解釋執(zhí)行了。
圍繞虛擬機(jī)的效率問(wèn)題展開(kāi)播歼,將涉及到一些優(yōu)化技術(shù)伶跷,例如:JIT、AOT。因?yàn)槿绻摂M機(jī)加載字節(jié)碼后叭莫,完全進(jìn)行解釋執(zhí)行蹈集,這勢(shì)必會(huì)影響執(zhí)行效率。所以雇初,對(duì)于這個(gè)運(yùn)行環(huán)節(jié)拢肆,虛擬機(jī)會(huì)進(jìn)行一些優(yōu)化處理,例如JIT技術(shù)靖诗,會(huì)將某些運(yùn)行特別頻繁的代碼編譯成機(jī)器碼郭怪。而AOT技術(shù),是在運(yùn)行前刊橘,通過(guò)工具直接將字節(jié)碼轉(zhuǎn)換為機(jī)器碼鄙才。