2014-01-09 37 views
0

近日,筆者研究如何虛擬機負載靜態變量,但我遇到一個問題如下:靜態變量加載過程

public class Example{ 

    static{ 
     num = 3; 
     System.out.print(num); 
    } 
    public static int num; 
} 

編譯器會報告錯誤。我認爲num有內存區域和價值。爲什麼我不能訪問num變量?

+4

在塊上方放置'public static int num;'(在定義之前不能引用一個字段)。我不知道它是否是一個錯字,但你忘了寫'int'。 – Maroun

+0

- 1代碼沒有編譯,但是你聲明瞭一個運行時錯誤,並且不知道哪一個錯誤。 –

+0

總是複製/粘貼錯誤和異常輸出。 –

回答

6

static塊和聲明執行他們編碼的順序。這意味着在執行靜態塊時,num字段尚未定義。

簡單的修復方法是將塊以上的聲明移動。

Java Language Specification Section 8.3.2.3(除其他事項外)說,一個變量可能分配之前被宣佈,但變量的值可能不是訪問的變量聲明之前,除非它的名稱是完全合格,所以這個編譯:

public class Example { 
    static{ 
     num = 3; // assignment OK without qualifying the name 
     System.out.print(Example.num); // name must be qualified to access value 
    } 
    public static int num; 
} 

還有更有趣的是,如果一個變量在聲明前被訪問,其默認值時,進一步對申報初始化仍然出現,所以這段代碼:

public class Example { 
    static{ 
     System.out.println(Example.num); // uses default value 
     num = 3;       // assignment OK 
     System.out.println(Example.num); // assigned value (3) is visible 
    } 

    public static int num = 1;   // initialization to 1 occurs 

    static{ 
     System.out.print(Example.num); // initialized value (1) is visible 
    } 
} 

產生這樣的輸出:

0 
3 
1 

哇!

+1

我讀過關於虛擬機加載類process.I的文章,我認爲num文件中的符號引用已經加載到虛擬機中,所以num變量已經被聲明。我誤解了嗎? – KrystalJake

+0

@KrystalJake閱讀編輯答案。有趣... – Bohemian

+0

很酷,我理解你的解釋!但是你能解釋一下爲什麼我可以使用完全限定的靜態變量來訪問它嗎?非常感謝。 – KrystalJake