2013-04-22 21 views
7

Il seguente codice sottrae semplicemente un valore (10 in questo caso, solo per la dimostrazione) dell'anno corrente ottenuto utilizzando la classe java.util.Calendar.Membri statici non inizializzati come previsto

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); 
    } 
} 

mi aspetto che questo codice per mostrare 2003 (anno in corso - 10), ma, invece, visualizza -10. Presumo che la costante YEAR non sia stata inizializzata. Perché succede in questo caso?

+3

prova a cambiare l'ordine delle dichiarazioni di '' test' e YEAT'. –

+0

@LouisWasserman anche se risolverà il suo problema - questo è un modo molto cattivo per comportarsi :) – alfasin

+0

È davvero molto cattivo avere questo tipo di codice dipendente dagli ordini in primo luogo, francamente. –

risposta

5

Questo accade perché si inizializza Test prima di aver inizializzato YEAR - il che significa che andrà al costruttore (implicito) e inizializzate eval-YEAR-10 prima YEAR ha un valore (in modo che il default è 0).

Come indicato nei commenti, è sufficiente modificare l'ordine di ANNO e TEST nell'inizializzazione.

+0

Ciao, considerando lo snippet di codice nella domanda un codice di enigma, ricordare l'ordine di valutazione è un compito odioso/noioso. – Tiny

5

Perché non è static - devi creare un oggetto per poter utilizzare questo campo! (O modificarlo per statico)

Prova:

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

Questo è ovvio, ma perché non funziona con 'TEST' come membro di istanza -' test TEST finale statico privato = nuovo Test(); TEST.eval; '? Grazie. – Tiny

+0

@Tiny Poiché quando TEST è in fase di inizializzazione, YEAT non è stato inizializzato e quindi il valore predefinito è 0. I campi statici vengono inizializzati in modo che vengano visualizzati. –

+0

@Tiny come ho detto: o dichiarare 'eval' come statico o creare un'istanza e usarlo. Non è possibile utilizzare una variabile di livello di classe con variabile a livello di istanza quando l'istanza non è stata ancora inizializzata. – alfasin

1

Fai eval statico e che funzionerà. Se non lo vuoi statico, esegui il calcolo nel metodo principale.

1

Come altri hanno già menzionato, il problema è nell'ordine dei campi statici. Ma, si può evitare il problema ordinazione interamente da pigramente inizializzazione TEST utilizzando un metodo (come avviene nel 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); 
    } 
} 
Problemi correlati