2012-04-05 20 views
12

Il seguente codice è il caso di riferimento legale avanti? se sì perché?Java Legal Forward Referencing

public class MyClass 
{ 
    private static int x = getValue(); 
    private static int y = 5; 
    private static int getValue() 
    { 
    return y; 
    } 
    public static void main(String[] args) 
    { 
    System.out.println(x); 
    } 
} 

risposta

19

Il codice sopra riportato è perfettamente legale Java. In Java, i campi statici vengono inizializzati come segue: innanzitutto, tutti i campi sono impostati sul valore predefinito per il loro tipo (0, false o null) e quindi inizializzati nell'ordine in cui sono dichiarati. Ciò significa che il codice di cui sopra è garantito per effettuare le seguenti operazioni:

  1. Set x e y a zero, dato che è il valore predefinito per int s.
  2. Inizializza x chiamando getValue(), che legge il valore di . Dal momento che y non è ancora stato inizializzato, ha ancora il valore 0.
  3. inizializzazione y a 5.

Ciò significa che x avrà il valore 0 e y prenderà il valore 5. Questo comportamento è portatile e garantito. You can see this here.

Spero che questo aiuti!

+0

Che cosa accadrebbe se quelle non fossero variabili statiche e metodo? – Vibhor

+2

Credo che il comportamento sia lo stesso: l'inizializzazione sta prima impostando tutto sul valore predefinito, quindi inizializzando ciascuno con il valore specificato, quindi chiamando il costruttore. – templatetypedef

+1

Quale, btw, è una delle ragioni per cui non si dovrebbe mai chiamare un metodo non final (o privato) da un costruttore; è troppo facile per qualcuno scavalcare quel metodo e vedere "questo" non ancora costruito, fino al punto di vedere un campo finale non inizializzato. – yshavit

5

Si può dire se è legale o meno dal fatto che esso compila; a differenza di altri linguaggi, Java non ha la nozione di "comportamento indefinito". Quello che succede qui è completamente spiegato. Può essere controintuitivo, ma è specificamente legale: è possibile accedere a una variabile statica prima di essere inizializzata da un metodo chiamato durante l'inizializzazione di un'altra variabile statica. Il caso superficialmente simile di accesso y direttamente da inizializzatore x s' - cioè

private static int x = y; 
private static int y = 5; 

è specificamente consentito. Non c'è davvero una forte ragione per cui - è solo come è.

+0

Cosa succede se le variabili non sono statiche ... il comportamento è lo stesso anche in questo caso? – Vibhor

+0

Sì, è effettivamente lo stesso. Le regole elencate per la statica sono leggermente differenti perché non esistono "costruttori" reali per una classe, ma gli oggetti sono inizializzati essenzialmente nello stesso modo. Ad esempio, variabili, inizializzatori e blocchi di istanze vengono anteposti, in ordine di apparizione, a ciascun costruttore. Per statica, inizializzatori e blocchi statici sono compilati, in ordine, in un unico metodo chiamato '()'. –

+0

Avere un programma che può essere testato con un compilatore è un lusso quando si tratta di domande come questa, temo.Questo è preso da un simulato esame per l'esame OCJP. Lo sto imparando ora, ed è proprio queste stupide domande che sono completamente inutili a prendere in giro l'intento dell'esame. –