[英]Static Initialization in Java?
我正在嘗試執行以下代碼:
public class StaticTest {
private static List<String> dat1;
{
dat1 = new ArrayList<>();
}
private StaticTest(){
System.out.println(dat1.contains("a")); //Marked Line 2: this one is not throwing
}
public static void main(String[] args) {
System.out.println(dat1.contains("a")); //Marked Line 1: This line throws null pointer
new StaticTest();
}
}
我嘗試執行上述代碼,在標記行1處得到了Null pointer exception
。但是當我注釋標記行1時,得到了輸出。
為什么我在第一種情況下而不在第二種情況下得到例外?
當我使用private static List<String> dat1= new ArrayList<>();
,不會引發異常。
簡單:
System.out.println(dat1.contains("a"));
運行一個構造函數(因為它在構造函數內部!)。 運行構造函數的一部分是:運行類的所有非靜態初始化程序塊。
鑒於:
public static void main(String[] args) {
System.out.println(dat1.contains("a")); //Marked Line 1: This line
只運行您的靜態初始化程序-但不運行構造函數代碼(確實- 在該行之后)。
因此,您的問題是此初始化程序塊:
{
dat1 = new ArrayList<>();
}
不是靜態的 !
換句話說:您的問題是由以非常不健康的方式混合靜態/非靜態引起的。 如果字段是static ,請確保使用靜態初始化代碼將其初始化。
順便說一句:合理的解決方案是簡單地做:
private final static List<String> data = new ArrayList<>();
這樣可以確保盡快初始化列表。 然后編譯器甚至會在您忘記初始化時告訴您。
這段代碼
{
dat1 = new ArrayList<>();
}
此構造函數塊。 將在super()之后的每個構造函數中執行該函數,因此它將不會在Mark1上運行。
如果您有這樣的代碼,則將在加載類時執行它。
static {
dat1 = new ArrayList<>();
}
更多詳細信息, 請參見http://www.jusfortechies.com/java/core-java/static-blocks.php
嗨@kajal,請參考以下正確的代碼:-
public class StaticTest {
private static List<String> dat1;
static
{
dat1 = new ArrayList<String>();
}
private StaticTest(){
System.out.println(dat1.contains("a")); //Marked Line 2: this one is not throwing
}
public static void main(String[] args) {
System.out.println(dat1.contains("a")); //Marked Line 1: This line throws null pointer
new StaticTest();
}
}
創建該類的實例時,將執行實例塊。 質疑為什么要獲取NullPointerException
:-請找到下面的StaticTest
類執行流程:-
Object
類2. java.lang
包類3. java.util.ArrayList
類。 dat1
分配內存。 main
方法並執行System.out.println(dat1.contains("a"));
被稱為null.contains("a");
解決了執行問題,但是正如我所說的,當您創建該類的實例時,將執行Instance塊。 因此,在創建對象new StaticTest();
時會初始化dat1
new StaticTest();
您的代碼:
{
dat1 = new ArrayList<>();
}
是一個非靜態初始化器。 當您使用以下方法調用構造函數時,將調用此方法: new StaticTest()
。 之后, dat1
將被初始化。
您可以在代碼前面加上static
關鍵字,從而將其更改為靜態初始化:
static
{
dat1 = new ArrayList<>();
}
然后它將適用於兩種情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.