簡體   English   中英

靜態變量初始化

[英]Static variable initialisation

每次創建包含這些變量的對象的新實例時,是否都會初始化靜態變量? 還是在首次調用對象時將它們初始化一次?

你說

實例靜態變量是否已初始化 ...

停在那兒,這句話沒有任何意義。 靜態變量存在於類中,而不存在於任何特定實例中。 它們是在創建實例,運行類上的靜態方法或訪問類上的靜態變量時運行的初始化過程中初始化的。 (完全公開,@ Bruno的回答使我知道了此信息)。

靜態字段是在類初始化期間初始化的(不要混合使用初始化加載 ,它們是不同的東西-可以加載類,並且您可以對它進行反射,而無需初始化它)。

同樣,如果您使用多個ClassLoader則給定類的類初始化可能會發生多次。

請參閱VM Spec 第2.17.4節“初始化 ”和第2.17.5節“詳細的初始化過程”,以獲取有關何時將完全加載類以及何時將其完全初始化的更多詳細信息。

編輯 :一個簡單的示例,它將顯示如何可以多次加載初始化一個類並且該加載不會自動暗示初始化:

public class A { static { System.out.println("I've been initialized!"); } }
public class Main {
  public static void main(String... args) {
    ClassLoader cl = new URLClassLoader(..., null);
    System.out.println("loading...");
    Class<?> aClass = cl.loadClass("A");
    // here you could perform reflection on aClass, without initializing it
    System.out.println("Will be initialized now:");
    Object o = aClass.newInstance();
    System.out.println("Let's load once again...");
    ClassLoader cl2 = new URLClassLoader(..., null);
    Class<?> aClass2 = cl2.loadClass("A");
    System.out.println("Will be initialized a second time:");
    Object o2 = aClass2.newInstance();

    // the following is false:
    System.out.println("aClass1.equals(aClass2) = " + aClass1.equals(aClass2));

    // the following is true:
    System.out.println("aClass1.getName().equals(aClass2.getName())" + aClass1.getName().equals(aClass2.getName()));
  }
}

(希望當您在URLClassLoader的構造函數中指定缺少的URL[]對象時,此函數可以編譯。)

請注意,有必要將類加載器的父級設置為null ,否則它們的父級將是主應用程序類加載器(即與加載類Main相同的類),因為默認情況下,Java首先將加載委托給父類加載器,如果類A在類路徑中,則只會看到一次加載和初始化。

最后,請注意, Class.load("A")不等同於classLoader.loadClass("A") 如果查看Class.load(String)的文檔,則會看到此方法加載初始化了該類。 Class.load(...)的重載Class.load(...)一個布爾值,指示是否應初始化該類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM