Java程序從源文件創(chuàng)建到程序運(yùn)行要經(jīng)過(guò)兩大步驟:1、源文件由編譯器編譯成字節(jié)碼(ByteCode)
網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專(zhuān)注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、小程序開(kāi)發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶(hù)創(chuàng)新互聯(lián)還提供了會(huì)昌免費(fèi)建站歡迎大家使用!
2、字節(jié)碼由java虛擬機(jī)解釋運(yùn)行。因?yàn)閖ava程序既要編譯同時(shí)也要經(jīng)過(guò)JVM的解釋運(yùn)行,所以說(shuō)Java被稱(chēng)為半解釋語(yǔ)言( "semi-interpreted" language)。
下面通過(guò)以下這個(gè)java程序,來(lái)說(shuō)明java程序從編譯到最后運(yùn)行的整個(gè)流程。代碼如下:
//MainApp.java
public class MainApp {
public static void main(String[] args) {
Animal animal = new Animal("Puppy");
animal.printName();
}
}
//Animal.java
public class Animal {
public String name;
public Animal(String name) {
this.name = name;
}
public void printName() {
System.out.println("Animal ["+name+"]");
}
}
第一步(編譯): 創(chuàng)建完源文件之后,程序會(huì)先被編譯為.class文件。Java編譯一個(gè)類(lèi)時(shí),如果這個(gè)類(lèi)所依賴(lài)的類(lèi)還沒(méi)有被編譯,編譯器就會(huì)先編譯這個(gè)被依賴(lài)的類(lèi),然后引用,否則直接引用,這個(gè)有點(diǎn)象make。如果java編譯器在指定目錄下找不到該類(lèi)所其依賴(lài)的類(lèi)的.class文件或者.java源文件的話(huà),編譯器話(huà)報(bào)“cant find symbol”的錯(cuò)誤。
編譯后的字節(jié)碼文件格式主要分為兩部分:常量池和方法字節(jié)碼。常量池記錄的是代碼出現(xiàn)過(guò)的所有token(類(lèi)名,成員變量名等等)以及符號(hào)引用(方法引用,成員變量引用等等);方法字節(jié)碼放的是類(lèi)中各個(gè)方法的字節(jié)碼。下面是MainApp.class通過(guò)反匯編的結(jié)果,我們可以清楚看到.class文件的結(jié)構(gòu):
第二步(運(yùn)行):java類(lèi)運(yùn)行的過(guò)程大概可分為兩個(gè)過(guò)程:1、類(lèi)的加載 2、類(lèi)的執(zhí)行。需要說(shuō)明的是:JVM主要在程序第一次主動(dòng)使用類(lèi)的時(shí)候,才會(huì)去加載該類(lèi)。也就是說(shuō),JVM并不是在一開(kāi)始就把一個(gè)程序就所有的類(lèi)都加載到內(nèi)存中,而是到不得不用的時(shí)候才把它加載進(jìn)來(lái),而且只加載一次。
下面是程序運(yùn)行的詳細(xì)步驟:
在編譯好java程序得到MainApp.class文件后,在命令行上敲java AppMain。系統(tǒng)就會(huì)啟動(dòng)一個(gè)jvm進(jìn)程,jvm進(jìn)程從classpath路徑中找到一個(gè)名為AppMain.class的二進(jìn)制文件,將MainApp的類(lèi)信息加載到運(yùn)行時(shí)數(shù)據(jù)區(qū)的方法區(qū)內(nèi),這個(gè)過(guò)程叫做MainApp類(lèi)的加載。
然后JVM找到AppMain的主函數(shù)入口,開(kāi)始執(zhí)行main函數(shù)。
main函數(shù)的第一條命令是Animal animal = new Animal("Puppy");就是讓JVM創(chuàng)建一個(gè)Animal對(duì)象,但是這時(shí)候方法區(qū)中沒(méi)有Animal類(lèi)的信息,所以JVM馬上加載Animal類(lèi),把Animal類(lèi)的類(lèi)型信息放到方法區(qū)中。
加載完Animal類(lèi)之后,Java虛擬機(jī)做的第一件事情就是在堆區(qū)中為一個(gè)新的Animal實(shí)例分配內(nèi)存, 然后調(diào)用構(gòu)造函數(shù)初始化Animal實(shí)例,這個(gè)Animal實(shí)例持有著指向方法區(qū)的Animal類(lèi)的類(lèi)型信息(其中包含有方法表,java動(dòng)態(tài)綁定的底層實(shí)現(xiàn))的引用。
當(dāng)使用animal.printName()的時(shí)候,JVM根據(jù)animal引用找到Animal對(duì)象,然后根據(jù)Animal對(duì)象持有的引用定位到方法區(qū)中Animal類(lèi)的類(lèi)型信息的方法表,獲得printName()函數(shù)的字節(jié)碼的地址。
開(kāi)始運(yùn)行printName()函數(shù)。
特別說(shuō)明:java類(lèi)中所有public和protected的實(shí)例方法都采用動(dòng)態(tài)綁定機(jī)制,所有私有方法、靜態(tài)方法、構(gòu)造器及初始化方法都是采用靜態(tài)綁定機(jī)制。而使用動(dòng)態(tài)綁定機(jī)制的時(shí)候會(huì)用到方法表,靜態(tài)綁定時(shí)并不會(huì)用到。
如果是java應(yīng)用程序,所有的都從main方法開(kāi)始;如果是applet小應(yīng)用程序,init()方法負(fù)責(zé)加載,start()方法開(kāi)始執(zhí)行;
Java Applet就是用Java語(yǔ)言編寫(xiě)的這樣的一些小應(yīng)用程序,它們可以直接嵌入到網(wǎng)頁(yè)中,并能夠產(chǎn)生特殊的效果。包含Applet的網(wǎng)頁(yè)被稱(chēng)為Java-powered頁(yè),可以稱(chēng)其為Java支持的網(wǎng)頁(yè)。
當(dāng)用戶(hù)訪問(wèn)這樣的網(wǎng)頁(yè)時(shí), Applet被下載到用戶(hù)的計(jì)算機(jī)上執(zhí)行,但前提是用戶(hù)使用的是支持Java的網(wǎng)絡(luò)l瀏覽器。由于Applet是在用戶(hù)的計(jì)算機(jī)上執(zhí)行的,因此它的執(zhí)行速度不受網(wǎng)絡(luò)帶寬或者M(jìn)odem存取速度的限制。用戶(hù)可以更好地欣賞網(wǎng)頁(yè)上Applet產(chǎn)生的多媒體效果。
jdk安裝好配置環(huán)境變量后,系統(tǒng)就承認(rèn)了 java,javac等命令,當(dāng)編譯好java文件,就可以在開(kāi)始——運(yùn)行——cmd的dos系統(tǒng)下運(yùn)用指定命令運(yùn)行java文件。
JDK 是整個(gè)Java的核心,包括了Java運(yùn)行環(huán)境,Java工具和Java基礎(chǔ)的類(lèi)庫(kù)。
JDK包含的基本組件包括:
javac – 編譯器,將源程序轉(zhuǎn)成字節(jié)碼
jar – 打包工具,將相關(guān)的類(lèi)文件打包成一個(gè)文件
javadoc – 文檔生成器,從源碼注釋中提取文檔
jdb – debugger,查錯(cuò)工具
java – 運(yùn)行編譯后的java程序(.class后綴的)
appletviewer:小程序?yàn)g覽器,一種執(zhí)行HTML文件上的Java小程序的Java瀏覽器。 Javah:產(chǎn)生可以調(diào)用Java過(guò)程的C過(guò)程,或建立能被Java程序調(diào)用的C過(guò)程的頭文件。 Javap:Java反匯編器,顯示編譯類(lèi)文件中的可訪問(wèn)功能和數(shù)據(jù),同時(shí)顯示字節(jié)代碼含義。 Jconsole: Java進(jìn)行系統(tǒng)調(diào)試和監(jiān)控的工具
總之,jdk并不是一個(gè)應(yīng)運(yùn)軟件,并不能從哪里運(yùn)行。編譯時(shí)在任何可輸入文本的軟件中均可(通常用.txt記事本編譯),編譯好后改名.java文件,在dos系統(tǒng)中用 javac命令編譯連接 java命令 .運(yùn)行。
.java文件的話(huà),非項(xiàng)目那種單篇幅的源代碼需要先進(jìn)行編譯,生成.class文件可以在命令控制臺(tái)下用java 文件名 進(jìn)行運(yùn)行,編譯java文件需要javac.exe程序 應(yīng)該是jdk中的工具,所以你需要下載jdk并配置環(huán)境變量,然后在控制臺(tái)運(yùn)行javac編譯源文件所在目錄下的java文件,會(huì)在本目錄下生成一個(gè)同名的.class文件
(沒(méi)有報(bào)錯(cuò)的情況下) ,然后運(yùn)行java 文件名 即可運(yùn)行該代碼(前提是你這篇文件需要有main方法)。