每次創建包含這些變量的對象的新實例時,都會初始化靜態變量嗎?或者當對象首次被調用時,它們是否只初始化一次?靜態變量初始化
靜態變量初始化
回答
你說
被初始化例如靜態變量...
停在那兒,聲明是沒有意義的。靜態變量存在於類中,而不是在任何特定的實例上。它們在初始化過程中初始化,該過程在創建實例,運行類的靜態方法或訪問類的靜態變量時運行。 (完全披露,@布魯諾的回答讓我知道這些信息)。
類加載!=類初始化。 –
@bruno「編譯器實際上做的是在內部產生一個類初始化例程,它按照它們出現在類聲明中的順序將所有靜態變量初始化器和所有靜態初始化器代碼塊組合在一起。只會在班級第一次加載時自動運行,一次。「從簡單的Java – hvgotcodes
hvgotcodes,不要相信書籍。 **這簡直是錯誤的**。去檢查虛擬機規格部分2.17.4和2.17.5(在我的答案下面的鏈接)。一個類在加載時不會被初始化。如果您使用多個類加載器,則可以多次加載一個類並進行多次初始化。 –
靜態字段的類(的初始化期間初始化不混合初始化和裝載,他們是不同的東西 - 一個類可以加載,你可以做反射就可以了,沒有永遠不會初始化它)。
此外,如果您使用多個ClassLoader
s,類初始化可能會多次發生給定的類。
見VM規格section 2.17.4, Initialization和section 2.17.5, Detailed initialization procedure關於更多的細節時,完全是一個類被加載,什麼時候它會被初始化..
編輯:簡單的例子,將顯示一個類如何被裝載和初始化多次,並且裝載並不自動意味着初始化:
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()));
}
}
(我希望當您指定的URLClass缺少URL[]
對象這個編譯裝載機的構造......)
注意,有必要設定的類加載器的父母null
,否則他們的父母將是主要的應用程序類加載器(即加載的類Main
),則因爲Java代表相同首先默認加載到父類加載器,如果類A
在類路徑中,則只會看到加載和初始化一次。
最後,請注意,Class.load("A")
不等於classLoader.loadClass("A")
。如果您檢查文檔Class.load(String)
,您會看到此方法加載和初始化該類。有一個Class.load(...)
超載,它需要一個布爾值來指示它是否應該初始化類。
可以一個類多次初始化?第2.17.5節中的一行表示「如果類或接口已經被初始化,則不需要進一步的操作。釋放對象的鎖並正常完成。」 – hvgotcodes
是的。在運行時,一個類由元組(ClassLoader,Package,Name)標識。如果你使用2個不相關的類加載器,你將有2 *個不同的*類(具有相同的名稱,以便它們各自的Class對象是!c1.equals(c2),但是c1.getName()。equals(c2)。 getName())是true),所以初始化過程可以每個發生一次。 –
- 1. 靜態變量初始化
- 2. 初始化靜態變量
- 3. 靜態變量初始化
- 4. 在C99中使用靜態變量初始化靜態變量
- 5. php初始化靜態變量與其他靜態變量
- 6. C++是靜態變量初始化= atomic?
- 7. 初始化自身靜態變量的
- 8. 靜態成員變量初始化C++
- 9. 初始化最終靜態變量
- 10. 靜態變量初始化順序
- 11. 靜態變量未初始化
- 12. 靜態成員變量初始化
- 13. 靜態只讀變量初始化
- 14. 初始化靜態最終變量
- 15. 靜態變量初始化 - 澄清
- 16. PHP的靜態變量初始化
- 17. 靜態變量重新初始化
- 18. 如何讓靜態變量初始化
- 19. 靜態變量未初始化
- 20. 靜態變量的初始化順序
- 21. 初始化靜態final變量聲明與初始化在Application.OnCreate()
- 22. 初始化後可以初始化靜態變量嗎?
- 23. 初始化靜態向量
- 24. 靜態局部變量和靜態局部對象初始化
- 25. 靜態初始化後聲明靜態變量
- 26. Java - 靜態初始化與靜態變量的默認值
- 27. 如何在JavaScript靜態類中初始化靜態變量?
- 28. 靜態塊VS中的靜態變量初始化順序
- 29. 靜態初始化
- 30. 如何讓靜態變量初始化爲全局變量
你是什麼意思的「實例靜態變量」?這就像談論「String int變量」。 –
有沒有這樣的事情作爲實例靜態變量。你有一個實例變量或靜態(類)變量! –
而且你不會調用一個對象 - 只有它的方法。 – DJClayworth