首頁  >  文章  >  Java  >  java類別載入器和類別反射使用範例

java類別載入器和類別反射使用範例

高洛峰
高洛峰原創
2017-01-13 09:22:331516瀏覽

一、一個指令對應一個進程。

當我們啟動一個Java程序,即啟動一個main方法時,都會啟動一個Java虛擬機進程,不管這個進程有多複雜。而不同的JVM進程之間是不會互相影響的。這也就是為什麼說,Java程式只有一個入口——main方法,讓虛擬機器呼叫。而兩個mian方法,對應的是2個JVM進程,啟動的是兩個不同的類別載入器,操作的實際上是不同的類別。故而不會互相影響。

二、類別載入。

當我們使用一個類,如果這個類別還未載入到記憶體中,系統會透過載入、連接、初始化對類別進行初始化。

1、類別載入:指的是將類別的class檔案讀入JVM,並為之建立一個Class物件。

2、類別連接:指的是把類別的二進位資料合併到JRE中,這又分為3個階段:

a)、校驗:檢查載入Class檔案資料的正確性。

b)、準備:給類別的靜態變數分配儲存空間,並進行預設初始化。

c)、解析:將類別的二進位資料中的符號引用替換成直接引用。

3、初始化:對類別的靜態變數、靜態初始化區塊進行初始化。

(注意:一個final類型的靜態屬性,如果在編譯時已經得到了屬性值,那麼調用該屬性時,不會導致該類別初始化,因為這個相當於使用常數;

使用ClassLoader()方法,只是載入該類,並未初始化。

類載入器就是負責將.class檔案載入到記憶體中,並為之產生對應的java.lang.Class對象,它負責載入所有的類,而一旦一個類別被載入到JVM中,就不會被再次載入了。

在Java中,一個類別以其全限定類別名稱(即套件名稱+類別名稱)作為標識。

而在JVM中,一個類別以其全限定類別名稱和其類別載入器作為識別。

JVM運行時會產生3個ClassLoader,分別為:BootstrapClassLoader(根類載入器)、ExtClassLoader(擴充類別載入器)和AppClassLoader(系統類別載入器)。 UML架構如下:

java類別載入器和類別反射使用範例其中,BootstrapClassLoader負責載入JRE的核心類別庫,它不是ClassLoader的子類,使用C++編寫,因此我們在Java中看不到它,透過其子類別的getParent( )方法取得時,將傳回null。 BootstrapClassLoader負責裝載JRE目標下的rt.jar、charsets.jar等Java核心類別庫。

如圖可知,ExtClassLoader和AppClassLoader為ClassLoader的子類別。在API中看不到它們,他們位於rt.jar檔案中。全限定類別名稱分別為:

sun.misc.Launcher$ExtClassLoader 與sun.misc.Launcher$AppClassLoader.

其中,ExtClassLoader負責裝載JRE擴充目錄ext中JAR套件,而AppClassLoader則負責裝載Classpath路徑下的類別套件path 。

測試如下:

package com.stopTalking.crazy;
public class TestClassLoader {
public static void main(String[] args) { 
//获取当前线程的类装载器  
ClassLoader loader = Thread.currentThread().getContextClassLoader();  
//获取System类的类装载器  
ClassLoader loader1 = System.class.getClassLoader();  
//获取本类TestClassLoader的类装载器loader2  
ClassLoader loader2 = TestClassLoader.class.getClassLoader();  
//获取loader2的父类  
ClassLoader loader3 = loader2.getParent();  
//获取loader2的父类的父类  
ClassLoader loader4 = loader3.getParent();  
System.out.println(loader);  
System.out.println(loader1);  
System.out.println(loader2);  
System.out.println(loader3);  
System.out.println(loader4);  
}  
}

控制台輸出:

//当前线程类获取的类加载器是AppClassLoader
sun.misc.Launcher$AppClassLoader@6b97fd
//System类为根装载器加载,java中访问不到,所以为null
null
//本类的类加载器当然也是AppClassLoader
sun.misc.Launcher$AppClassLoader@6b97fd
sun.misc.Launcher$ExtClassLoader@1c78e57
null

更多java類加載器和類反射使用示例相關文章請關注PHP中文網!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn