2014-05-04 102 views
2

下面的示例類不編譯:爲什麼最終的實例變量需要初始化,當一個最終的局部變量沒有?

class Test { 
    final int x; // Compilation error: requires initialization. 
} 

此代碼的編譯錯誤信息是:

..\src\pkgs\main\Test.java:3: error: variable x might not have been initialized 
class Test { 
^ 

然而,Java不會生成包含下面的方法的類的任何錯誤信息:

class Test { 
    void method() { 
     final int x; // Compiles OK; has no initialization. 
    } 
} 

有關初始化和要求,爲什麼Java的治療最終我nstance變量和最終局部變量的區別?謝謝。

+2

爲什麼很難知道。一個可能的參數:最終變量必須在使用之前初始化 - 如果不使用,則不需要初始化。最後一個字段必須在構造函數的末尾進行初始化 - 此時對象及其所有字段都可供任何人使用,編譯器不應該英勇地解決它是否可能被訪問。 –

回答

1

任何使用,即讀,第二種情況給你一個error。但是未使用的變量算作警告,而不是錯誤;運行的代碼的含義是明確的,如果很可能是錯誤的。

對於構造函數的情況,並不存在編譯器執行的那種未使用的變量分析,如果僅僅因爲(對於除私有字段之外的任何其他變量),它可能在編譯器無法訪問的另一個文件中讀取。

所以需要將它作爲一個錯誤來避免,以避免運行時行爲,最終取決於未指定的JVM實現細節。

2

實例隱式使用實例變量。您給出的局部變量示例不使用局部變量,因此沒有錯誤(該變量未被使用)。

如果您嘗試使用x局部變量例如將無法編譯(有相同的錯誤):

class Test { 

    Test() { 
     final int x; 
     System.out.println(x); // <== Compilation error - "variable x might not have been initialized" 
    } 
} 

類似地,精細提供你的第一個例子中,你做在某些時候初始化變量,不一定在聲明中:

class Test { 
    final int x; 

    Test() { 
     this.x = 10; 
    } 
} 
+1

@AlanStokes:我意識到我沒有處理另一半。希望現在它可以。 –

0

最終的attricutes應該在構造函數中初始化,這就是爲什麼它不能在你的例子中編譯。 最終變量在使用前也應該初始化。聲明它沒有初始化的方法是很好的。