2012-10-05 10 views
5

Abbiamo davvero bisogno di costanti finali statiche in Java?Utilizzo di metodi che restituiscono un valore costante

Si supponga che ho il seguente codice:

public class Test { 

    public static final int A = 1234; 

    public static int getA() 
    { 
     return 1234; 
    } 
} 

Potete per favore confrontare i seguenti due casi in termini di efficienza?

  1. Test.A

  2. Test.getA()

+0

http://codebetter.com/raymondlewallen/2005/07/19/4-major-principles-of-object-oriented-programming/ – talnicolas

+0

Sono curioso di sapere che cosa sarà il bytecode. Un metodo 'static' che restituisce una variabile' static final' sembra altamente ottimizzabile. – Brian

risposta

9

Assumendo un compilatore JIT, non ci dovrebbero essere differenze evidenti di efficienza - almeno non abbastanza per fare una differenza significativa nella velocità di esecuzione della vostra applicazione.

C'è un notevole guadagno di flessibilità, tuttavia: incapsulare il valore in un metodo è quasi sempre buono, perché consente di modificare il modo in cui il valore viene calcolato in seguito.

Un'eccezione degna di nota a questa regola è pura costante, ad esempio, dal mondo della matematica: non ha molto senso incapsulare l'accesso a Math.PI, perché non c'è possibilità che il valore di questa costante fondamentale cambierà , suggerendo la necessità di cambiare il metodo il valore è ottenuto nel tuo programma.

+0

+1 per il guadagno di flessibilità. – Gamb

+0

Math.PI un buon esempio – Jayy

+1

Tanto più che i riferimenti alle costanti vengono copiati letteralmente nel codice che li utilizza, quindi se una costante cambia, qualsiasi codice che lo utilizza deve essere ricompilato per ottenere il nuovo valore. –

1

In termini di efficienza, test.getA() spesso può essere ridotto ad un equivalente di test.A da JIT. Tuttavia, la differenza sarebbe trascurabile al meglio.

Abbiamo davvero bisogno di costanti finali statiche in Java?

No, ma aiuta a prevenire l'allocazione ripetuta.

+0

La JIT lo ottimizzerà, ma questa non è [analisi di fuga] (http://docs.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html#escapeAnalysis). – Jesper

+0

@Jesper, dopo aver aggiornato la memoria sull'argomento, penso che tu abbia ragione –

0

Il caso che si mostra è abbastanza banale, che credo sia inteso. Il tuo primo caso è più diretto ed efficiente in quanto è una chiamata in meno in pila, ma credo che uno stile di codifica migliore sarebbe quello di combinare i due. Presumo che questo non sarà l'unico posto in cui usi questa variabile nella tua classe.

public class Test { 

public static final int A = 1234; 

public static int getA() 
{ 
    return A; 
} 

public static int doSomething() 
{ 
    int result = A * 10; 
    //do more stuff 
    return result; 
} 
} 

Questo consente di modificare solo la variabile in un posto se mai bisogno di cambiare e ottenere il risultato atteso in tutto il programma. Personalmente, renderei int un privato solo per coerenza dell'utilizzo di un metodo get, che è come devono essere impostate le classi. In questo modo non ti imbatterai mai in un problema in cui non ti ricordi se hai bisogno di '()' dopo il nome della variabile e tutte le variabili che vivono al di fuori della classe sono accessibili nello stesso modo. La maggior parte di questo è solo uno stile di codifica e non è giusto o sbagliato.

1

Le variabili finali statiche non possono essere modificate da codice esterno, quindi non è necessario incapsularle.

Inoltre, un metodo statico senza parametri suggerisce l'accesso allo stato di un oggetto, che è una bugia, poiché il metodo è statico.

Compilatore-saggio non ci dovrebbe essere molta differenza in termini di efficienza, ma per quanto riguarda la leggibilità del programma e il codice di auto-documentazione, la finale statica è un'opzione migliore e testata nel tempo.

2

Le costanti staticfinal si comportano in modo diverso rispetto ai valori letterali restituiti da un metodo. Il compilatore java li usa anche in alcuni casi in fase di compilazione.

Un esempio,

public static boolean DEBUG = false; 

... 

if (DEBUG) 
{ 
    ...do something... 
} 

vs.

public boolean debug() 
{ 
    return false; 
} 

... 

if (debug()) 
{ 
    ...do something 2... 
} 

Nel primo caso, la condizione e ... fare qualcosa ... codice non sarà incluso nel byte-codice compilato (il file di classe). Nel secondo caso, la condizione e ... fare qualcosa 2 ... il codice sarà incluso ma mai eseguito - il JIT potrebbe fare un'analisi sufficiente in questo caso, sebbene per rimuovere il codice in fase di esecuzione.

Una volta, nei primi giorni di Java, il JIT non esisteva o non era abbastanza intelligente da ottimizzare il semplice metodo che restituisce un valore letterale. Quindi era necessario un valore costante per le prestazioni. È anche più conveniente definire costanti in questo modo se si tiene presente che le classi esterne (per le costanti finali statiche pubbliche/protette) avranno il valore inserito in quel codice byte in fase di compilazione; piuttosto che ottenere il valore dalla classe sorgente in fase di esecuzione.

Problemi correlati