2013-09-24 15 views
32

Chi può spiegare cosa sta succedendo?Il blocco statico non viene chiamato

public class MagicFinal { 

    public static void main(String[] args) { 
     System.out.println(A.s); 
    } 
} 

class A { 
    static { 
     System.out.println("class has been loaded"); 
    } 

    public static final String s = "final"; 

    public static final Integer i = 3; 


} 

Console:

finale

cosa si tratta? Non capisco perché la classe non sia stata caricata, so che le lezioni vengono sempre caricate alla prima chiamata. Il campo s è in un pool di stringhe e vedo che il modificatore finale è magico. campo ho cambiato:

Se cancello modificatore finale (public static String s = "final") mi metterò

Console:

classe è stata caricata

finale

Nota i: public static final int i = 3; e mostralo in conso le. Ho ottenuto lo stesso come nella situazione di stringa. Perché?

risposta

46

"final" è un stringa letterale e come tale è un compile-time constant expression. Il valore di una variabile static final inizializzata con un'espressione di costante in fase di compilazione è direttamente codificata nella classe che fa riferimento a esso e non viene fatto alcun riferimento alla classe di origine. Pertanto l'inizializzazione della classe di origine non si verifica.

Come punto laterale, si prega di notare la distinzione tra classe carico e categoria inizializzazione: unica occorrenza di quest'ultimo è proprio specificato dal JLS. Il caricamento della classe può avvenire in qualsiasi momento.

+1

Ok, grazie mille !! Che dire int ?? public static final int i = 3; // non è stata caricata la classe di scrittura public static final Intero i = 3; // è stata caricata la classe di scrittura – idmitriev

+4

Leggere la definizione dell'espressione della costante in fase di compilazione a cui ho collegato la risposta. 'int' è un valore primitivo,' String' è l'unico caso speciale di un valore tipizzato di riferimento che può essere coinvolto in un'espressione costante e 'Integer' non è né l'uno né l'altro. –

+0

@marko - Mi stai dicendo che la Classe A non viene caricata affatto ?? o è un caso di inizializzazione pigra ??? – TheLostMind

3

Questo è ciò che è scritto in Java Language Specification {8.3.2.1 Initializers for Class Variables}. Questo deve rispondere alla tua domanda

Una sottigliezza è che, in fase di esecuzione, variabili statiche che sono definitive e che vengono inizializzati con fase di compilazione valori costanti vengono inizializzati prima. Questo anche si applica a tali campi nelle interfacce (§9.3.1). Queste variabili sono "costanti" che non verrà mai osservato in con i loro valori iniziali predefiniti (§4.12.5), anche con i programmi subdoli . Vedi §12.4.2 e §13.4.9 per ulteriori discussioni.

+0

Sembra che tu ti stia riferendo a * The Java Language Specification, Third Edition *. Non ci sono tali paragrafi in * Java® Language Specification Java SE 7 Edition *. – johnchen902

+0

Sì. È giusto. Stavo esaminando la vecchia edizione ma la dichiarazione vale anche per JLS 7. Le righe sottostanti sono tratte da JLS7 In fase di esecuzione, i campi statici finali e inizializzati con le espressioni costanti (§15.28) vengono inizializzati per primi (§12.4.2). Questo vale anche per tali campi nelle interfacce (§9.3.1). Questi campi sono "costanti" che non saranno mai osservati a hanno i loro valori iniziali predefiniti (§4.12.5), anche da programmi subdoli (§ 13.4.9). –