2012-01-07 16 views
25

La mia domanda è piuttosto semplice:
Il compilatore considera tutti i metodi in una classe finale come se fossero definitivi? L'aggiunta della parola chiave final ai metodi di una classe finale ha qualche effetto?Metodi non finali in una classe finale

Ho capito che i metodi finali hanno una migliore possibilità di essere in linea e questo è il motivo per cui lo chiedo.

Grazie in anticipo.

risposta

26

Hai ragione, tutti i metodi in una classe finale sono implicitamente definitivi.

See here:

"Si noti che è possibile anche dichiarare un intero finale di classe. Una classe che è dichiarato finale non può essere sottoclasse. Ciò è particolarmente utile, per esempio, quando si crea una classe immutabile, come il Classe di stringhe. "

And here:

Tutti i metodi in una classe finale sono implicitamente finale.

questo può anche essere di interesse per voi: Performance tips for the Java final keyword

+2

Per essere pedante, è discutibile se i metodi siano implicitamente definitivi o meno; non c'è alcuna possibilità di tentare di scavalcarli! –

+0

Ciò significa che il compilatore tratterà questi metodi come finali? (inlining) @OliCharlesworth True, ma c'è una differenza nel modo in cui il compilatore tratta i metodi virtuali e finali. – Acidic

+1

@Acidic: vedere il terzo link che ho appena aggiunto. Probabilmente non hai bisogno di uscire dal tuo modo di dichiarare le cose come definitive. Ma sì, per il compilatore, quei metodi sono considerati "finali". – EboMike

5

può essere il compilatore li tratta come finale.

le seguenti stampe "false":

final class FinalClass { 
    public void testMethod() {} 
} 

Method method = FinalClass.class.getDeclaredMethod("testMethod"); 
int m = method.getModifiers(); 
System.out.println(Modifier.isFinal(m)); 
7

fa il compilatore a trattare tutti i metodi di una classe finale in quanto definitiva se stessi?

In effetti sì. Non è possibile sovrascrivere un metodo in una classe final. L'aggiunta (o la rimozione) di una parola chiave final a un metodo non fa differenza con questa regola.

L'aggiunta della parola chiave finale ai metodi in una classe finale ha qualche effetto?

In pratica, ha un effetto minimo. Non ha alcun effetto sulle regole di overriding (vedi sopra), e nessun effetto sulla inlining (vedi sotto).

E 'possibile dire in fase di esecuzione se un metodo è stato dichiarato con una parola chiave final ... utilizzando la riflessione per osservare i flag del metodo. Quindi ha un effetto un po ', anche se un effetto che è irrilevante per il 99,99% dei programmi.

Ho capito che i metodi finali hanno una migliore possibilità di essere in linea e questo è il motivo per cui lo chiedo.

Questa comprensione è errata.Il compilatore JIT in una JVM moderna tiene traccia di quali metodi non sono sovrascritti nelle classi caricate da da un'applicazione. Utilizza queste informazioni e i tipi statici per determinare se una determinata chiamata richiede o meno l'invio di classi virtuali. In caso contrario, è possibile eseguire l'inlining e verrà utilizzato a seconda della dimensione del corpo del metodo. In effetti, il compilatore JIT ignora la presenza/assenza di final e utilizza un metodo più accurato per rilevare le chiamate ai metodi in cui è consentita l'inclusione del metodo.

(in realtà è più complessa. Un'applicazione può caricare dinamicamente sottoclassi che causano analisi metodo di sostituzione del compilatore JIT diventare non corretto. In questo caso, la JVM deve invalidare qualsiasi metodo compilati effettuate e causare loro di essere . ricompilato)


La conclusione è:

  • v'è alcun vantaggio prestazioni in aggiunta ai metodi final in final classi.

  • Ci

    potrebbe essere un vantaggio prestazionale in final a metodi non final classi, ma solo se si sta utilizzando un vecchio Sun JVM, o qualche altra piattaforma Java/Java-like con una scarsa qualità del compilatore JIT.

Se vi preoccupate per le prestazioni, è meglio utilizzare una piattaforma Java up-to-date/alte prestazioni con un compilatore JIT decente rispetto ad inquinare il codice-base con final parole chiave che sono suscettibili di causare problemi in futuro.


Hai scritto in un commento:

@RussellZahniser Ho letto in modo diverso in molti luoghi.

Internet è pieno di vecchie informazioni, molte delle quali non aggiornate ... o non è mai stato corretto in primo luogo.

+0

Grazie, questa è una lettura molto interessante. C'è qualche informazione ufficiale o qualche tipo di test e risultati definitivi sull'argomento? – Acidic

+0

Inoltre, in una domanda pertinente che ho chiesto prima, sono stato portato a capire che i metodi 'final' hanno in effetti una maggiore possibilità di essere sottolineati: http: // stackoverflow.it/questions/8639704/probability-of-getter-and-setters-getting-inlined-by-the-compiler – Acidic

+1

@Acidic - la mia comprensione è che "final" non fa alcuna differenza, e non conosco alcuna prova reale che contraddica questo . Se vuoi davvero una risposta definitiva, guarda il codice sorgente OpenJDK e vedi cosa fanno effettivamente i compilatori JIT. –

Problemi correlati