2013-04-22 61 views
7

以下代碼僅從當前年份中使用java.util.Calendar類減去一個值(本例中爲10,僅用於演示)。靜態成員未按預期初始化

public final class Test 
{ 
    private static final Test TEST = new Test(); 
    private static final int YEAR = Calendar.getInstance().get(Calendar.YEAR); 
    private final int eval=YEAR - 10; 

    public static void main(String[] args) 
    { 
     System.out.println("Evaluation "+TEST.eval); 
    } 
} 

我希望這段代碼能夠顯示2003(當前年份 - 10),但它會顯示-10。我假設常量YEAR尚未初始化。爲什麼在這種情況下會發生?

+3

嘗試切換'TEST'和'YEAT'的聲明的順序。 – 2013-04-22 23:33:07

+0

@LouisWasserman即使它可以解決他的問題 - 這是一個非常非常頑皮的行爲方式:) – alfasin 2013-04-22 23:57:02

+0

坦率地說,首先有這種依賴訂單的代碼非常非常淘氣。 – 2013-04-23 00:36:03

回答

5

這是因爲要初始化Test已初始化YEAR之前 - 這意味着它會去(隱含的)構造並初始化evalYEAR-10YEAR之前有一個值(所以它默認爲0)。

正如在註釋中所表示的那樣,只需在初始化中更改YEAR和TEST的順序即可。

+0

嗨,考慮到難題代碼中的代碼片段,記住評估的順序是一個可惡的/乏味的任務。 – Tiny 2013-04-26 09:05:52

5

因爲它不是static - 您必須創建一個對象才能使用此字段! (或者將其更改爲靜態)

嘗試:

public final class Test 
{ 
    private static final Test TEST = new Test(); 
    private static final int YEAR = Calendar.getInstance().get(Calendar.YEAR);  
    private final int eval=YEAR - 10; 

    public static void main(String[] args) 
    { 
     Test t = new Test(); 
     System.out.println("Evaluation "+t.eval); 
    } 
} 
+0

這是顯而易見的,但爲什麼它不能用'TEST'作爲實例成員 - 'private static final Test TEST = new Test(); TEST.eval;'?謝謝。 – Tiny 2013-04-22 23:40:36

+0

@Tiny因爲當TEST被初始化時,YEAT沒有被初始化,因此默認爲0.靜態字段按照它們出現的順序被初始化。 – 2013-04-22 23:41:56

+0

@就像我說的那樣:要麼聲明'eval'爲靜態的,要麼創建一個實例並使用它。當實例尚未初始化時,不能將實例級變量用於類級變量。 – alfasin 2013-04-22 23:54:24

1

eval靜電,它會工作。如果你不希望它是靜態的,那麼在主要方法中進行計算。

1

正如其他人所說,問題是在靜態字段的順序。但是,你可以使用的方法延遲初始化TEST(如在singleton pattern完成)完全避免了排序問題:

public final class Test 
{ 
    private static Test TEST = null; 
    private static final Test getInstance() { 
     if (TEST == null) { 
      TEST = new Test(); 
     } 
     return TEST; 
    } 

    private static final int YEAR = Calendar.getInstance().get(Calendar.YEAR); 
    private final int eval=YEAR - 10; 

    public static void main(String[] args) 
    { 
     System.out.println("Evaluation "+Test.getInstance().eval); 
    } 
}