這集視頻我會從Helloworld出發(fā)衰抑,先講一講一個java類由哪些構(gòu)成抒倚,然后在介紹Java語法之前先說一說為啥Java要用類刹衫,滿足一下初學(xué)者的好奇心荧琼。我們在寫C語言程序的時候,一般一來就int main了咖杂,但是寫java的時候卻要public class啥啥啥的庆寺,為啥什么都要用類呢?這要從Java的平臺無關(guān)性說起诉字,為此我把跟平臺相關(guān)的C++語言作為對比懦尝。什么叫平臺無關(guān)性呢,就是你在Linux系統(tǒng)里面寫一段Java代碼壤圃,把它編譯了陵霉,把編譯好的代碼放到windows平臺也能運(yùn)行,怎么做到的呢伍绳?
首先Java支持平臺無關(guān)性有三個要素踊挠,C++是將編譯好的代碼直接放在操作系統(tǒng)上運(yùn)行的,但是Java不一樣冲杀,Java運(yùn)行在Java虛擬機(jī)這個平臺上效床,這個平臺扮演著Java程序所在的機(jī)器硬件和系統(tǒng)之間的緩沖角色,這樣Java程序只需與Java平臺打交道权谁,而不用管具體的操作系統(tǒng)剩檀。第二,Java基本的數(shù)據(jù)類型的值域和和行為由自己定義旺芽,而C++基本數(shù)據(jù)類型由它的占位寬度決定沪猴,占位寬度由所在的平臺決定。第三采章、Java語言編譯成.class文件运嗜,這是一種字節(jié)碼,其格式由嚴(yán)格的定義悯舟,Java虛擬機(jī)只用關(guān)心編譯成的字節(jié)碼的內(nèi)容担租,將.class字節(jié)碼作為中間橋梁,因此可做到與平臺無關(guān)抵怎。
說到.class字節(jié)碼翩活,我就先拿出一個概念阱洪,Java運(yùn)行在Java虛擬機(jī)上面,Java虛擬機(jī)只認(rèn)得到.class字節(jié)碼的文件菠镇,實(shí)際上除了Java語言冗荸,JRuby、Groovy利耍、Scala等程序都能編譯成.class文件蚌本,Java虛擬機(jī)并不關(guān)心.class文件的來源是哪種語言。說到這里我就要簡要提一下了C++語言的編譯過程就在這里跟Java有很大區(qū)別隘梨,首先我們來看C++語言的編譯過程:
C++的編譯與鏈接過程主要由以下步驟組成,預(yù)處理程癌、編譯和優(yōu)化、匯編生成目標(biāo)文件轴猎、鏈接嵌莉、生成可執(zhí)行文件。
預(yù)處理過程主要就是替換宏捻脖、刪除注釋锐峭、處理預(yù)處理命令,編譯和優(yōu)化階段就是進(jìn)行詞法語法語義分析可婶,然后生成匯編指令沿癞。匯編生成目標(biāo)文件階段中生成的目標(biāo)文件主要包含數(shù)據(jù)和二進(jìn)制代碼指令和兩個表,未解決符號表和導(dǎo)出符號表矛渴,分別告訴鏈接器自己需要什么和能夠提供什么椎扬。由于目標(biāo)文件在程序中可能調(diào)用了某個庫文件中的函數(shù),因此不能立即執(zhí)行具温,這個時候就需要鏈接程序?qū)⒛繕?biāo)文件和這些鏈接在一起蚕涤,生成可執(zhí)行文件∠承桑回看整個編譯過程我們發(fā)現(xiàn)揖铜,在編譯和優(yōu)化階段,它的過程是依賴于機(jī)器的硬件結(jié)構(gòu)的剂习,比如如何充分利用機(jī)器的各個硬件寄存器存放有關(guān)變量的值,另外生成的可執(zhí)行文件是直接在操作系統(tǒng)上運(yùn)行的较沪,也跟平臺有關(guān)鳞绕。
但是Java語言的編譯過程就不一樣了:
Java代碼的編譯過程由Javac編譯器完成,Javac編譯器將Java代碼編譯成Java虛擬機(jī)能夠識別的一種語言尸曼,即.class字節(jié)碼们何,然后由Java虛擬機(jī)將它轉(zhuǎn)化為當(dāng)前這個機(jī)器能夠識別的機(jī)器語言。每一個.class文件由每一個.java文件編譯而來控轿,它的規(guī)范比較嚴(yán)格冤竹,有很多約定拂封,它就要求每一個.java文件都必須要有一個主類,而且類的名字必須要跟文件名一致鹦蠕,這應(yīng)該也是為了統(tǒng)一.class字節(jié)碼的規(guī)范的需要冒签。
另外,從兩種語言的入口函數(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)行的時候噪伊,它會首先分析你的.class文件中有沒有定義main函數(shù)簿煌,如果有,就會把main函數(shù)在的當(dāng)前類裝載到內(nèi)存中酥宴,完成一些初始化操作啦吧,然后執(zhí)行main函數(shù)體。