2015-05-28 13 views
8

Ora, di recente mi sono imbattuto in una raccomandazione che dovresti usare la parola chiave finale il più ampia possibile. Ciò è utile per evitare che un programmatore riprenda la propria gamba, ovvero riassegna la variabile che non dovrebbe essere riassegnata.La parola chiave final ha qualche impatto sulla JVM?

Ma serve qualche altro obiettivo? Cioè, JVM può usare le informazioni sulle variabili finali per ottimizzare il bytecode in qualche modo, quindi sarebbe più veloce (costruire un pipelining migliore o usarlo in un ambiente multithread)? O è solo uno zucchero sintattico che minimizza la possibilità di errori durante lo sviluppo del codice?

+0

finale o si può dire aiuto costante nelle ottimizzazioni del compilatore. es .: - Piegatura costante, Propagazione costante –

+0

Correlati: http://stackoverflow.com/questions/3961881/why-defining-class-as-final-improves-jvm-performance?rq=1 – Patrick

+0

"O è solo uno zucchero sintattico che minimizza la possibilità di errori durante lo sviluppo del codice? " Il pensiero intelligente effettivo minimizza gli errori. Senza di ciò, la parola chiave finale non è solo zucchero sintattico, ma anche un placebo. – Gimby

risposta

4

IBM states:

Come molti miti circa le prestazioni di Java, la convinzione erronea che dichiarando classi o metodi come i risultati finali in una migliore performance è opinione diffusa ma raramente esaminata. L'argomento dice che dichiarare un metodo o una classe come finale significa che il compilatore può chiamare il metodo inline in modo più aggressivo, perché sa che in fase di esecuzione questa è sicuramente la versione del metodo che verrà chiamato. Ma questo non è semplicemente vero.Solo perché la classe X è compilata rispetto alla classe finale Y non significa che verrà caricata la stessa versione della classe Y in fase di esecuzione. Pertanto, il compilatore non può in linea tali chiamate di metodi cross-class in modo sicuro, definitivo o meno. Solo se un metodo è privato, il compilatore lo può inline liberamente e, in tal caso, la parola chiave finale sarebbe ridondante.

4

Per quanto riguarda le variabili, Java è abbastanza intelligente da capire che una variabile non viene modificata da nessuna parte nel metodo e utilizzare questa conoscenza per scopi di ottimizzazione. Non è necessario che tu contrassegni una variabile final per saperlo.

I metodi sono una storia leggermente diversa: quando si contrassegna un metodo final, Java può richiamare tale metodo più veloce, perché non ha più bisogno di controllare per le sue sostituzioni. Tuttavia, l'hotspot è abbastanza intelligente da capire che non ci sono override, con o senza l'uso di final.

Generalmente, tuttavia, questa raccomandazione ha lo scopo di rendere il vostro codice più facile da leggere e capire dagli altri: fare una variabile finale indica ai lettori che si sta facendo una costante; fare una finale di classe dice ai tuoi lettori che la classe non è progettata per l'ereditarietà; fare un metodo finale dice ai tuoi lettori che la logica di quel metodo dovrebbe rimanere invariata attraverso la gerarchia dell'ereditarietà. Nel lungo periodo, questa informazione è più preziosa del potenziale per ottimizzare il codice in esecuzione.

+0

E i metodi privati? Hanno bisogno di una parola chiave finale? Dopotutto, non possono assolutamente essere ignorati. –

+0

@ SPIRiT_1984 I metodi 'private' non hanno bisogno di essere marcati' final' - traggono vantaggio dalla stessa ottimizzazione dei metodi finali (i metodi 'static' ottengono anche questo, perché non possono essere sovrascritti in Java). – dasblinkenlight

+0

"Java" (l'hotspot in realtà) è in genere abbastanza intelligente da capire se un metodo non viene mai sovrascritto e comunque esegue tali ottimizzazioni, quindi sì, l'ultimo paragrafo. – Voo

1

i metodi finali possono essere o meno allineati dalla JVM fino a quando non vengono caricati dalla JVM. Quindi, se sei sicuro che il metodo non verrà ridefinito, contrassegnalo come finale.

Le costanti devono sempre essere statiche finali poiché saranno immutabili e jvm non ha bisogno di tenere traccia di queste variabili poiché non cambieranno mai.

+0

_se sei sicuro che il metodo non verrà ridefinito, contrassegnalo come finale._ Non sarei mai sicuro di questo a meno che non conoscessi un motivo per cui il metodo _must_ non può essere ridefinito (ad esempio, se viene chiamato da un costruttore). Solo perché non riesco a pensare a un motivo per scavalcare un metodo non significa che qualche altro programmatore non penserà a un motivo. –

+0

@ james-large, in genere, quando si costruisce una libreria e si desidera controllare quali classi e metodi sono "consentiti" per essere sovrascritti, la parola chiave final offre solo un meccanismo per farlo. Questo è ciò che intendevo con la mia affermazione. – Farhad

+1

Giusto, e non vorrei mai controllarlo a meno che non sapessi di un caso speciale in cui un client che sovrascriva potrebbe impedire a una delle classi _my_ di comportarsi nel modo in cui avevo promesso che si sarebbe comportata. –

1

Penso che questa raccomandazione sia un po 'troppo aspecifica.

Ad esempio; Raccomanderei di evitare l'utilizzo finale di classi e metodi per impostazione predefinita (poiché le classi finali interrompono i test di unità).

Inoltre, trovo che usare la finale per i parametri del metodo sia solo uno spreco di "spazio su schermo" (e da ciò: sprecare "energia" sul lato del lettore).

D'altra parte, avere solo attributi finali per le classi può trasformare oggetti di tali classi in oggetti immutabili; e questa è una buona cosa.

Come vedi; ci sono molti pro e contro sull'uso della finale; e penso che la "leggibilità" vada spesso oltre i "potenziali" miglioramenti delle prestazioni.

Problemi correlati