三種建立Class對象的差別

今日查看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

相關文章
相關標籤/搜索