2013-05-07 20 views
6

我注意到了靜態初始化程序中的某些內容,這可能是javac中的一個錯誤。我已經構建了一個場景,我可以爲變量賦值但不能讀取該值。如果在聲明之前放置了靜態初始化程序錯誤

這兩個例子如下,第一個編譯正常,第二個在嘗試從tmp讀取值時出錯,但由於某種原因,允許將值賦給tmp。我可以理解它是否既不能讀取也不能寫入變量,因爲在靜態初始化器之後聲明瞭tmp,但只有其中一個錯誤對我沒有意義。

//Compiles Successfully: 
public class Script 
{ 
    public static Object tmp; 
    static 
    { 
     tmp = new Object(); 
     System.out.println(tmp); 
    } 

} 

//error only on the read but not the assignment 
public class Script 
{ 

    static 
    { 
     tmp = new Object(); 
     System.out.println(tmp); 
    } 
    public static Object tmp; 
} 

要進一步強調這一點,這確實編譯成功。

public class Script 
{ 

    static 
    { 
     tmp = new Object(); 
    } 
    public static Object tmp; 
} 
+0

我相信[對類似問題的回答] [1]比我能更好地回答這個問題。這是奇怪的行爲,但不是一個錯誤。它正在做它應該做的事情。 [1]:http://stackoverflow.com/a/10035928/348975 – emory 2013-05-07 14:03:02

+0

我不確定它是否存在,靜態初始化器在那裏從它們的默認值初始化變量。也就是說static int v = 1;等價於static int v;靜態{v = 1;} – 2013-05-07 14:06:43

+0

@Dukeling我寫了我的評論作爲答案和StackOverflow確定我的答案是微不足道的(我認爲這意味着太短)並自動將其轉換爲評論,但顯然使鏈接流失。 – emory 2013-05-07 14:12:34

回答

3

看來這是在規範中定義(見JLS 8.3.2.3):

一個成員的聲明中需要以文本方式出現之前,它是僅用於 如果成員是一個實例(分別爲靜態的 一個類或接口C和所有以下條件)字段保持:

  • 在一個實例(分別靜態發生的使用)VARI (或靜態)初始值設定項
    C.

  • 該用法不在分配的左側。

  • 用法是通過一個簡單的名字。

  • C是內部使用的最內層類或接口。

因此,如果使用是在賦值的左側,那麼它是合法的,因爲第二個不成立了。

+0

好的,我購買它是規範的一部分,但這似乎是一個非常奇怪的事情,指定 – 2013-05-07 14:19:47

+0

有時候我認爲Java不僅僅需要一個規範,還有另一本書來解釋它的決定。我希望有人能夠對此有更多的瞭解,但規範是我能找到的最好的。 – 2013-05-07 14:22:46