概述
Java程序從創(chuàng)建源文件到程序運(yùn)行要經(jīng)歷兩個(gè)主要步驟:
- 源文件 編譯器編譯> 字節(jié)碼文件(ByteCode)。
- 字節(jié)碼文件 JVM解釋運(yùn)行> 在內(nèi)存中運(yùn)行
Java程序從編譯到運(yùn)行
示例程序:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public class ClassA{ public static void main(String[] args){ ClassB b = new ClassB( "b" ); b.method(); } } class ClassB{ private String name; public ClassB(String name){ this .name = name; } public void method(){ System.out.println( "ClassB method()" ); } } |
編譯
- 源文件被編譯成.class文件。
- 若一個(gè)類所依賴的類還沒有編譯,則先編譯被依賴的類,然后引用。
- 若已編譯,則直接引用。
- 若找不到指定類的文件,則拋出cannot find symbol錯(cuò)誤。
-
編譯后生成的字節(jié)碼文件由兩部分組成:
- 常量池:代碼中的所有token(類名,成員變量名)和符號(hào)引用(方法引用,成員變量引用)
- 方法字節(jié)碼:類中各個(gè)方法的字節(jié)碼。
運(yùn)行
Java類的運(yùn)行過程:
- 類的加載
- 類的執(zhí)行
注:
JVM在程序第一次主動(dòng)使用類的時(shí)候才加載類,而不是一開始將所有的類都加載到內(nèi)存中,只加載一次。
詳細(xì)步驟:
- 系統(tǒng)啟動(dòng)一個(gè)JVM進(jìn)程,JVM從classpath路徑中查找對(duì)應(yīng)的字節(jié)碼文件,將對(duì)應(yīng)的類信息加載到運(yùn)行時(shí)數(shù)據(jù)區(qū)的方法區(qū)內(nèi)(類的加載)。
- JVM找到類的主函數(shù)入口,執(zhí)行main函數(shù)。
- 若需創(chuàng)建對(duì)象,而方法區(qū)沒有該類的信息,則加載對(duì)應(yīng)的類,并把類信息放入方法區(qū)。
- 加載所需的類后,JVM在堆區(qū)中為實(shí)例對(duì)象分配內(nèi)存,并調(diào)用構(gòu)造函數(shù)初始化實(shí)例。(該實(shí)例有指向方法區(qū)對(duì)應(yīng)類的類信息的引用)
- 當(dāng)調(diào)用實(shí)例的方法時(shí),JVM由對(duì)象引用找到堆中的對(duì)象,再由對(duì)象持有的引用定位到方法區(qū)中類的類型信息的方法表,從而獲得待調(diào)用函數(shù)的字節(jié)碼的地址。
- 開始執(zhí)行調(diào)用的函數(shù)。
注:
- public和protected的實(shí)例方法采用動(dòng)態(tài)綁定機(jī)制:要用到方法表。
- private,static,構(gòu)造器和初始化方法采用靜態(tài)綁定機(jī)制:不需要方法表。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://www.cnblogs.com/truestoriesavici01/p/13217279.html