Java代碼到底是如何運行起來的?
程序運行的兩種形式:
1、通過採用jar包的形式
2、war包---->tomcat
1個Java文件從編碼完成到最終執行,一般主要包括兩個過程:
1、編譯
2、運行
編譯
1、寫好代碼後,會通過編譯器將代碼編成.class後綴的字節碼文件。
2、Java是與平臺無關的,一次編寫到處運行,實現語言無關性的基礎就是虛擬機和字節碼存儲格式。
3、只要編譯器按照虛擬機規範,編譯成對應的 .clsss 文件,這個.class文件就能被JVM加載。不同的操作系統通過對應的版本載入這個.classs文件,則實現餓平臺無關性。
運行
運行,則是把編譯聲稱的.class文件交給Java虛擬機(JVM)執行。
而我們所說的類加載過程即是指JVM虛擬機把.class文件中類信息加載進內存,並進行解析生成對應的class對象的過程。
類加載
1、JVM要運行這些.class字節碼文件中年的代碼,那就把.class文件中的各種類給加載進來,這就涉及到類加載的過程。
2、通過類加載器,可以把編譯好的.class字節碼文件給加載到JVM中。
類加載的過程主要分爲三個部分:
-
加載
-
鏈接
-
初始化
加載
簡單來說,加載指的是把class字節碼文件從各個來源通過類加載器裝載入內存中。
這裏有兩個重點:
1、字節碼來源。一般的加載來源包括從本地路徑下編譯生成的.class文件,從jar包中的.class文件,從遠程網絡,以及動態代理實時編譯
2、類加載器。一般包括啓動類加載器,擴展類加載器,應用類加載器,以及用戶的自定義類加載器。
注:爲什麼會有自定義類加載器?
1、一方面是由於java代碼很容易被反編譯,如果需要對自己的代碼加密的話,可以對編譯後的代碼進行加密,然後再通過實現自己的自定義類加載器進行解密,最後再加載。
2、另一方面也有可能從非標準的來源加載代碼,比如從網絡來源,那就需要自己實現一個類加載器,從指定源進行加載。
而鏈接又可以細分爲三個小部分:
-
驗證
-
準備
-
解析
鏈接
在類被加載後,需通過鏈接過程將它合併到JVM的運行狀態之中,然後纔可以執行。鏈接過程分三個步驟。
1、驗證
假設.class文件本人篡改了,不符合JVM的規範,那麼JVM是沒法去執行的。
2、準備
準備工程中,給內部的類變量分配內存空間並設置默認的初始值。準備並不會執行具體的代碼。
int 變量設置默認初始值爲0
3、解析
確保這些被引用的類被正確找到,這個過程可能會導致其他的java類被加載進來。
初始化
在鏈接完成之後,會對類初始化的過程,初始化的過程主要操作的是靜態代碼快和靜態變量。
需要注意的點:
1、一個類被初始化之前,它的直接父類也需要被初始化。
2、一個接口的初始化不會引起其父接口的初始化。
總結
首先從Idea中編寫代碼,然後通過編譯器將代碼轉化爲.class(字節碼)文件。這個字節碼文件必須是遵循JVM規範的。編譯後通過類加載到JVM中。然後執行鏈接過程:驗證、準備和解析。鏈接階段完成之後進行初始化操作,對靜態代碼塊和靜態變量進行初始化。