類字面常量


Java還提供了另一種方法來生成對Class對象的引用,即使用類字面常量。
這樣做不僅更簡單,而且更安全,因為它在編譯時就會受到檢查(因此不需要置於try語句塊中),並且它根除了對forName方法的引用,所以也更高效。類字面常量不僅可以應用於普通的類,也可以應用於接口、數組以及基本數據類型。

當使用“.class”來創建對Class對象的引用時,不會自動地初始化該Class對象,初始化被延遲到了對靜態方法(構造器隱式的是靜態的)或者非final靜態域(注意final靜態域不會觸發初始化操作)進行首次引用時才執行。而使用Class.forName時會自動的初始化。

為了使用類而做的准備工作實際包含三個步驟:
- 加載:由類加載器執行。查找字節碼,並從這些字節碼中創建一個Class對象
- 鏈接:驗證類中的字節碼,為靜態域分配存儲空間,並且如果必需的話,將解析這個類創建的對其他類的所有引用。
- 初始化:如果該類具有超類,則對其初始化,執行靜態初始化器和靜態初始化塊。

package example;

import java.util.Random;

class Initable {
    static final int staticFinal = 47;
    static final int staticFinal2 = Test.rand.nextInt(1000);

    static {
        System.out.println("Initializing Initable");
    }
}
class Initable2 {
    static int staticNonFinal = 147;

    static {
        System.out.println("Initializing Initable2");
    }
}
class Initable3 {
    static int staticNonFinal = 74;

    static {
        System.out.println("Initializing Initable3");
    }
}
public class Test  {
    public static Random rand=new Random(47);
    public static void main(String[] args){
        
        Class initable = Initable.class;
        System.out.println("After creating Initable ref");
      
        System.out.println(Initable.staticFinal);
       
        System.out.println(Initable.staticFinal2);//開始初始化

        System.out.println(Initable2.staticNonFinal);

        try {
            Class initable3 = Class.forName("example.Initable3"); //立即初始化
        } catch (ClassNotFoundException e) {
            System.out.println("Can't find Initable3");
            System.exit(1);
        }
        System.out.println("After creating Initable3 ref");
        System.out.println(Initable3.staticNonFinal);
    
    
        
    }
    
}

輸出:

After creating Initable ref
47
Initializing Initable
258
Initializing Initable2
147
Initializing Initable3
After creating Initable3 ref
74

 

可以得出:

1.僅適用 .class語法來獲得類的引用不會引發初始化,但是用Class.forname()就立即進行了初始化。

2,如果一個Static final值是編譯器常量,就像staticFinal那樣,那么這個值不需要對Initable類進行初始化時就

可以被讀取,但是如果一個域設置為static和final,還不足以確保這種行為,例如,Initable.staticFinal2的訪問將會

強制進行類的初始化,因為他不是一個編譯器常量。

3如果一個域是static但不是final的,那么在對他進行訪問時,總是要求他在被讀取之前,要先進行鏈接(為這個域分配存儲空間)和

初始化(初始化該存儲空間),就像對Initable2.staticNonFinal訪問看到的結果


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM