2013-01-31 79 views
8

誰能解釋一下什麼是錯這個代碼:非法向前參考java的問題

public class Base { 


    static { 
     i = 1; 
     System.out.println("[Base]after static init block i=" + i);// LINE 1 
     System.out.println("*************************************"); 
     System.out.println(); 
    } 
    static int i; 



    public static void main(String[] args) { 
     System.out.println(Base.i); 
    } 
} 

如果我註釋行1 - 一切正常,並Base.main方法打印「1」。 如果LINE 1 - 未被註釋,則編譯時錯誤:「非法正向引用」。 因此,正如我所瞭解的靜態初始化塊,我可以爲我設置值,但不能讀取。誰能解釋爲什麼?

回答

14

這是因爲restrictions on the use of Fields during Initialization的。特別是,靜態初始化塊內聲明的行之前的靜態字段只能在表達式的左側(即賦值),除非它們是完全限定的(在你的情況下爲Base.i)。

例如:如果您在i = 1;之後插入int j = i;,您將得到相同的錯誤。

解決該問題的顯而易見的方法是在之前聲明static int i;靜態初始化塊。

2

「非法正向引用」意味着您正在嘗試在定義之前使用變量。

您觀察到的行爲是javac錯誤的症狀(請參閱此錯誤報告)。這個問題似乎在新版本的編譯器中得到修復,例如OpenJDK的7

看看

Illegal forward reference error for static final fields

+1

我不認爲問題中描述的行爲是一個錯誤。 – assylias

2

你的代碼更改爲:

int i; 
static { 
    i = 1; 
    System.out.println("[Base]after static init block i=" + i);// LINE 1 
    System.out.println("*************************************"); 
    System.out.println(); 
} 
3

可以在靜態塊添加基地的變量i或你有塊之前我聲明靜態INT。其他解決方案是創建靜態方法,而不是靜態塊。

static { 
    Base.i = 1; 
    System.out.println("[Base]after static init block i=" + Base.i);// LINE 1 
    System.out.println("*************************************"); 
    System.out.println(); 
} 
+0

+1好點.. – assylias

+0

它足以在System.out語句中添加Base,謝謝。 – Timofei