今日查看java中Class對象的詳解時遇到這個問題。html
Class對象的建立有三種方式:java
用測試類Test舉例函數
1.測試
Class.forName("Test")
2..net
Test.class
3.htm
new Test().getClass()
可是這三種方式的實現不同。對象
/** * Created by Administrator on 2016/8/1. */ public class test { public static void main(String[] args) { try { //1.測試Class.forName() // Class testTypeForName=Class.forName("TestClassType"); // System.out.println("testForName---"+testTypeForName); //2.測試類名.class // Class testTypeClass=TestClassType.class; // System.out.println("testTypeClass---"+testTypeClass); //3.測試Object.getClass() // TestClassType testGetClass= new TestClassType(); // System.out.println("testGetClass---"+new TestClassType().getClass()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } class TestClassType{ //構造函數 public TestClassType(){ System.out.println("----構造函數---"); } //靜態的參數初始化 static{ System.out.println("---靜態的參數初始化---"); } //非靜態的參數初始化 { System.out.println("----非靜態的參數初始化---"); } }
依次打開三種註釋掉的方式運行後獲得的結果blog
1.接口
---靜態的參數初始化---內存
testForName---class TestClassType
2.
testTypeClass---class TestClassType
3.
---靜態的參數初始化---
----非靜態的參數初始化---
----構造函數---
testGetClass---class TestClassType
第三種方式可能原來就知道這是一個類實例化的過程,可是對前兩種建立Class類的方式原理不太瞭解。而後查了一下。
1.概述
Class文件由類裝載器裝載後,在JVM中將造成一份描述Class結構的元信息對象,經過該元信息對象能夠獲知Class的結構信息:如構造函數,屬性和方法等,Java容許用戶藉由這個Class相關的元信息對象間接調用Class對象的功能。
虛擬機把描述類的數據從class文件加載到內存,並對數據進行校驗,轉換解析和初始化,最終造成能夠被虛擬機直接使用的Java類型,這就是虛擬機的類加載機制。
2.工做機制
類裝載器就是尋找類的字節碼文件,並構造出類在JVM內部表示的對象組件。在Java中,類裝載器把一個類裝入JVM中,要通過如下步驟:
(1) 裝載:查找和導入Class文件;
(2) 連接:把類的二進制數據合併到JRE中;
(a)校驗:檢查載入Class文件數據的正確性;
(b)準備:給類的靜態變量分配存儲空間;
(c)解析:將符號引用轉成直接引用;
(3) 初始化:對類的靜態變量,靜態代碼塊執行初始化操做
Java程序能夠動態擴展是由運行期動態加載和動態連接實現的;好比:若是編寫一個使用接口的應用程序,能夠等到運行時再指定其實際的實現(多態),解析過程有時候還能夠在初始化以後執行;好比:動態綁定(多態);
在JVM加載類的時候,須要通過三個步驟,裝載、連接、初始化。裝載就是找到相應的class文件,讀入JVM,初始化就不用說了,最主要就說說連接。
連接分三步,第一步是驗證class是否符合規格,第二步是準備,就是爲類變量分配內存同時設置默認初始值,第三步就是解析,而這步就是可選的。
Class類中的forName方法最後調用的方法
/** Called after security check for system loader access checks have been made. */ private static native Class<?> forName0(String name, boolean initialize, ClassLoader loader, Class<?> caller) throws ClassNotFoundException;
參數initialize應該是是否解析。
ClassLoader中的loadClass方法最後調用的方法
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException
方法裏面有這麼一段
if (resolve) { resolveClass(c); }
參數resolve應該也是是否解析的標識。
因此最開始的.class就是沒有解析,而Class.forName()方法是解析了。
參考資料:http://blog.csdn.net/yuebinghaoyuan/article/details/7244123
http://www.iteye.com/topic/83978
http://www.cnblogs.com/ITtangtang/p/3978102.html