2013-07-26 4 views
5

Quando compilo:javac trattando un statica finale diverso basato sul metodo di assegnazione

public static final boolean FOO = false; 
public static final void fooTest() { 
    if (FOO) { 
     System.out.println("gg"); 
    } 
} 

ottengo un metodo vuoto fooTest() {}. Tuttavia quando compilo:

static boolean isBar = false; 
public static final boolean BAR = isBar; 
public static final void fooTest() { 
    if (BAR) { 
     System.out.println("gg"); 
    } 
} 

l'istruzione if è inclusa nel file di classe compilato. Questo significa che ci sono due diversi "tipi" di final static in java, o si tratta solo di un'ottimizzazione del compilatore?

+5

Il compilatore può valutare espressioni costituite solo da 'static final's e costanti letterali in fase di compilazione ed eseguire ottimizzazioni secondo necessità. La prima espressione può essere valutata in fase di compilazione; il secondo non può, perché si basa su un'espressione non finale. – dasblinkenlight

+2

Ciò non significa che la compilazione bytecode JIT la lascerà naturalmente. –

risposta

7

Nel primo caso, il compilatore esegue un'ottimizzazione. Sa che Foo sarà sempre false e ucciderà il codice che non sarà mai raggiunto.

Nel secondo caso, si assegna il valore della variabile non finale isBar a BAR. Il compilatore non può sapere se la variabile isBar è stata modificata da qualche altra parte, specialmente se non è privata. Pertanto non è sicuro del valore di BAR. Quindi non può fare l'ottimizzazione.

+1

Non è proprio un'ottimizzazione del compilatore in quanto tale. È un comportamento richiesto dalla specifica del linguaggio Java. (* Costante tempo di compilazione * è la frase magica.) 'Private' è irrilevante - potrebbe trovarsi in un file diverso in un altro pacchetto senza nemmeno il codice sorgente disponibile. –

2

Nel primo caso i campi static final sono costanti che sono note al tempo compile. Quindi il compilatore ottimizza e in linea il constant.

Nel secondo caso il campo è non-finalvariable e non può essere delineato dal compilatore in quanto può cambiare.

class Test{ 
    public static final boolean BOOL = true; //CONSTANT KNOWN AT COMPILE TIME 


    public void someMethod(){ 
     while(BOOL){ 
      //some code 
     } 
    } 


    //OPTIMIZED VERSION DONE BY COMPILER 
    public void someMethod(){ 
     while(true){ //There is no need for accessing BOOL if it is not going to change and compiler understands that so inlines the value of constant 


     } 
    } 

} 

Potete guardare il codice compilato utilizzando alcuni strumenti di de-compilatore e troverete il metodo ottimizzato che ho scritto nel file di classe.

2

È puramente un caso di ottimizzazione del compilatore in cui ignora un incarico diretto e considera l'assegnazione indiretta di valori letterali.

0

Potrebbe esserci solo un valore statico esistente nella memoria. Nel primo blocco, la variabile finale statica FOO viene impostata come valore falso, in quanto nota al compilatore e quindi ottimizza l'istruzione if in esso. Ma in seconda affermazione, la variabile statica finale BAR viene assegnata al valore di variabile statica isBar, che a sua volta non consente al compilatore di ottimizzare l'istruzione if (poiché isBar potrebbe essere qualsiasi valore booleano e non può essere determinato perché java supporta polymorphism ei valori vengono assegnati a variabili dinamicamente durante il tempo di esecuzione.), quindi la posizione di memoria delle variabili statiche nel secondo blocco è importante per determinare il valore del compilatore, dove come nel primo blocco il valore falso è noto senza alcuna assegnazione tra variabili diverse ed è ottimizzato.

Problemi correlati