這集視頻我會(huì)從Helloworld出發(fā)杏瞻,先講一講一個(gè)java類由哪些構(gòu)成捞挥,然后在介紹Java語(yǔ)法之前先說(shuō)一說(shuō)為啥Java要用類砌函,滿足一下初學(xué)者的好奇心垦沉。我們?cè)趯?xiě)C語(yǔ)言程序的時(shí)候厕倍,一般一來(lái)就int main了讹弯,但是寫(xiě)java的時(shí)候卻要public class啥啥啥的,為啥什么都要用類呢悲靴?這要從Java的平臺(tái)無(wú)關(guān)性說(shuō)起癞尚,為此我把跟平臺(tái)相關(guān)的C++語(yǔ)言作為對(duì)比。什么叫平臺(tái)無(wú)關(guān)性呢蛋褥,就是你在Linux系統(tǒng)里面寫(xiě)一段Java代碼膜廊,把它編譯了淫茵,把編譯好的代碼放到windows平臺(tái)也能運(yùn)行匙瘪,怎么做到的呢丹喻?
首先Java支持平臺(tái)無(wú)關(guān)性有三個(gè)要素谅猾,C++是將編譯好的代碼直接放在操作系統(tǒng)上運(yùn)行的税娜,但是Java不一樣概行,Java運(yùn)行在Java虛擬機(jī)這個(gè)平臺(tái)上占锯,這個(gè)平臺(tái)扮演著Java程序所在的機(jī)器硬件和系統(tǒng)之間的緩沖角色消略,這樣Java程序只需與Java平臺(tái)打交道,而不用管具體的操作系統(tǒng)胎撤。第二伤提,Java基本的數(shù)據(jù)類型的值域和和行為由自己定義,而C++基本數(shù)據(jù)類型由它的占位寬度決定舶沛,占位寬度由所在的平臺(tái)決定如庭。第三、Java語(yǔ)言編譯成.class文件哟楷,這是一種字節(jié)碼否灾,其格式由嚴(yán)格的定義,Java虛擬機(jī)只用關(guān)心編譯成的字節(jié)碼的內(nèi)容挎狸,將.class字節(jié)碼作為中間橋梁锨匆,因此可做到與平臺(tái)無(wú)關(guān)舞痰。
說(shuō)到.class字節(jié)碼响牛,我就先拿出一個(gè)概念矢赁,Java運(yùn)行在Java虛擬機(jī)上面,Java虛擬機(jī)只認(rèn)得到.class字節(jié)碼的文件,實(shí)際上除了Java語(yǔ)言,JRuby、Groovy褒纲、Scala等程序都能編譯成.class文件,Java虛擬機(jī)并不關(guān)心.class文件的來(lái)源是哪種語(yǔ)言。說(shuō)到這里我就要簡(jiǎn)要提一下了C++語(yǔ)言的編譯過(guò)程就在這里跟Java有很大區(qū)別酒朵,首先我們來(lái)看C++語(yǔ)言的編譯過(guò)程:
C++的編譯與鏈接過(guò)程主要由以下步驟組成,預(yù)處理、編譯和優(yōu)化匙铡、匯編生成目標(biāo)文件即纲、鏈接蜂厅、生成可執(zhí)行文件唇跨。
預(yù)處理過(guò)程主要就是替換宏飞主、刪除注釋、處理預(yù)處理命令,編譯和優(yōu)化階段就是進(jìn)行詞法語(yǔ)法語(yǔ)義分析魁瞪,然后生成匯編指令。匯編生成目標(biāo)文件階段中生成的目標(biāo)文件主要包含數(shù)據(jù)和二進(jìn)制代碼指令和兩個(gè)表,未解決符號(hào)表和導(dǎo)出符號(hào)表利朵,分別告訴鏈接器自己需要什么和能夠提供什么。由于目標(biāo)文件在程序中可能調(diào)用了某個(gè)庫(kù)文件中的函數(shù),因此不能立即執(zhí)行,這個(gè)時(shí)候就需要鏈接程序?qū)⒛繕?biāo)文件和這些鏈接在一起瞻佛,生成可執(zhí)行文件文搂。回看整個(gè)編譯過(guò)程我們發(fā)現(xiàn)然遏,在編譯和優(yōu)化階段姨裸,它的過(guò)程是依賴于機(jī)器的硬件結(jié)構(gòu)的那先,比如如何充分利用機(jī)器的各個(gè)硬件寄存器存放有關(guān)變量的值,另外生成的可執(zhí)行文件是直接在操作系統(tǒng)上運(yùn)行的,也跟平臺(tái)有關(guān)。
但是Java語(yǔ)言的編譯過(guò)程就不一樣了:
Java代碼的編譯過(guò)程由Javac編譯器完成幔烛,Javac編譯器將Java代碼編譯成Java虛擬機(jī)能夠識(shí)別的一種語(yǔ)言,即.class字節(jié)碼,然后由Java虛擬機(jī)將它轉(zhuǎn)化為當(dāng)前這個(gè)機(jī)器能夠識(shí)別的機(jī)器語(yǔ)言运杭。每一個(gè).class文件由每一個(gè).java文件編譯而來(lái),它的規(guī)范比較嚴(yán)格报嵌,有很多約定血筑,它就要求每一個(gè).java文件都必須要有一個(gè)主類困曙,而且類的名字必須要跟文件名一致赂弓,這應(yīng)該也是為了統(tǒng)一.class字節(jié)碼的規(guī)范的需要。
另外,從兩種語(yǔ)言的入口函數(shù)調(diào)用也是各具特色车柠。
C/C++的運(yùn)行環(huán)境中的上層.c文件調(diào)用C Runtime startup中的void mainCRTStartup(void)函數(shù),它在執(zhí)行了一系列初始化操作,比如獲取命令行參數(shù)稽寒,獲取環(huán)境變量值负芋,初始化全局變量漫蛔,初始化IO的所需各項(xiàng)準(zhǔn)備后,調(diào)用main(argc,argv)
Java則不同旧蛾,在編譯生成了.class字節(jié)碼文件了之后莽龟,在虛擬機(jī)上運(yùn)行的時(shí)候,它會(huì)首先分析你的.class文件中有沒(méi)有定義main函數(shù)锨天,如果有毯盈,就會(huì)把main函數(shù)在的當(dāng)前類裝載到內(nèi)存中,完成一些初始化操作病袄,然后執(zhí)行main函數(shù)體搂赋。