L'uso della parola chiave finale in Java migliora le prestazioni?


347

In Java vediamo molti luoghi in cui è finalpossibile utilizzare la parola chiave ma il suo utilizzo è raro.

Per esempio:

String str = "abc";
System.out.println(str);

Nel caso sopra, strpuò essere, finalma questo è comunemente lasciato fuori.

Quando un metodo non verrà mai sostituito, possiamo usare la parola chiave finale. Allo stesso modo nel caso di una classe che non verrà ereditata.

L'uso della parola chiave finale in uno o tutti questi casi migliora davvero le prestazioni? Se è così, allora come? Spiega per favore. Se l'uso corretto delle finalcose veramente importanti per le prestazioni, quali abitudini dovrebbe sviluppare un programmatore Java per utilizzare al meglio la parola chiave?


Non credo che amico, il dispacciamento dei metodi (chiamata nella cache del sito e ...) sia un problema nei linguaggi dinamici non nei linguaggi di tipo statico
Jahan,

Se eseguo il mio strumento PMD (plug-in per eclissi) utilizzato a scopo di revisione, mi viene suggerito di apportare modifiche alla variabile nel caso mostrato sopra. Ma non ho capito il suo concetto. Davvero la performance colpisce così tanto ??
Abhishek Jain,

5
Pensavo fosse una tipica domanda d'esame. Ricordo che finale ha avere influenza sulle prestazioni, IIRC classi finali possono essere ottimizzate dal JRE, in qualche modo, perché non possono essere sottoclasse.
Kawu,

In realtà ho avuto questo test. Su tutte le JVM che ho testato l'uso di final su variabili locali ha migliorato le prestazioni (leggermente, ma tuttavia può essere un fattore nei metodi di utilità). Il codice sorgente è nella mia risposta di seguito.
Rustyx,

1
"l'ottimizzazione prematura è la radice di tutti i mali". Lascia che il compilatore faccia il suo lavoro. Scrivi codice leggibile e commentato. Questa è sempre la scelta migliore!
Kaiser

Risposte:


285

Di solito no. Per i metodi virtuali, HotSpot tiene traccia del fatto che il metodo sia stato effettivamente sovrascritto ed è in grado di eseguire ottimizzazioni come l'inserimento sul presupposto che un metodo non è stato ignorato, fino a quando non carica una classe che sovrascrive il metodo, a quel punto può annullare (o annullare parzialmente) tali ottimizzazioni.

(Naturalmente, questo presuppone che tu stia utilizzando HotSpot, ma è di gran lunga la JVM più comune, quindi ...)

A mio avviso, dovresti utilizzarlo in finalbase a design e leggibilità chiari piuttosto che per motivi di prestazioni. Se si desidera modificare qualcosa per motivi di prestazioni, è necessario eseguire misurazioni appropriate prima di piegare il codice più chiaro fuori forma, in questo modo è possibile decidere se qualsiasi prestazione aggiuntiva raggiunta merita la leggibilità / progettazione più scadente. (Nella mia esperienza non è quasi mai valsa la pena; YMMV.)

EDIT: come sono stati menzionati i campi finali, vale la pena sottolineare che spesso sono comunque una buona idea, in termini di design chiaro. Cambiano anche il comportamento garantito in termini di visibilità cross-thread: dopo che un costruttore ha completato, tutti i campi finali sono garantiti per essere immediatamente visibili in altri thread. Questo è probabilmente l'uso più comune finalnella mia esperienza, anche se come sostenitore della regola empirica "progettare l'ereditarietà o proibirlo" di Josh Bloch, dovrei probabilmente usare finalpiù spesso per le lezioni ...


1
@Abhishek: a proposito di cosa in particolare? Il punto più importante è l'ultimo: che quasi sicuramente non dovresti preoccuparti di questo.
Jon Skeet,

9
@Abishek: finalè generalmente raccomandato perché semplifica la comprensione del codice e aiuta a trovare i bug (perché rende esplicita l'intenzione dei programmatori). PMD probabilmente consiglia di utilizzare a finalcausa di questi problemi di stile, non per motivi di prestazioni.
sleske,

3
@Abhishek: molto probabilmente sarà specifico per JVM e potrebbe fare affidamento su aspetti molto sottili del contesto. Ad esempio, credo che il server HotSpot JVM consentirà comunque di incorporare metodi virtuali se sottoposto a override in una classe, con un rapido controllo del tipo, ove appropriato. Ma i dettagli sono difficili da definire e potrebbero cambiare tra i rilasci.
Jon Skeet,

5
Qui vorrei citare Effective Java, 2nd Edition, punto 15, Minimizzare mutevolezza: Immutable classes are easier to design, implement, and use than mutable classes. They are less prone to error and are more secure.. Inoltre An immutable object can be in exactly one state, the state in which it was created.vs Mutable objects, on the other hand, can have arbitrarily complex state spaces.. Dalla mia esperienza personale, l'uso della parola chiave finaldovrebbe evidenziare l'intenzione dello sviluppatore di inclinarsi verso l'immutabilità, non per "ottimizzare" il codice. Ti incoraggio a leggere questo capitolo, affascinante!
Louis F.

2
Altre risposte mostrano che l'uso della finalparola chiave sulle variabili potrebbe ridurre la quantità di bytecode, il che potrebbe produrre un effetto sulle prestazioni.
Julien Kronegg,

86

Risposta breve: non ti preoccupare!

Risposta lunga:

Quando parli delle variabili locali finali, tieni presente che l'uso della parola chiave finalaiuterà il compilatore a ottimizzare staticamente il codice , il che alla fine potrebbe risultare in un codice più veloce. Ad esempio, le stringhe finali a + bnell'esempio seguente sono concatenate staticamente (al momento della compilazione).

public class FinalTest {

    public static final int N_ITERATIONS = 1000000;

    public static String testFinal() {
        final String a = "a";
        final String b = "b";
        return a + b;
    }

    public static String testNonFinal() {
        String a = "a";
        String b = "b";
        return a + b;
    }

    public static void main(String[] args) {
        long tStart, tElapsed;

        tStart = System.currentTimeMillis();
        for (int i = 0; i < N_ITERATIONS; i++)
            testFinal();
        tElapsed = System.currentTimeMillis() - tStart;
        System.out.println("Method with finals took " + tElapsed + " ms");

        tStart = System.currentTimeMillis();
        for (int i = 0; i < N_ITERATIONS; i++)
            testNonFinal();
        tElapsed = System.currentTimeMillis() - tStart;
        System.out.println("Method without finals took " + tElapsed + " ms");

    }

}

Il risultato?

Method with finals took 5 ms
Method without finals took 273 ms

Testato su Java Hotspot VM 1.7.0_45-b18.

Quindi, quanto costa l'effettivo miglioramento delle prestazioni? Non oso dirlo. Nella maggior parte dei casi probabilmente marginale (~ 270 nanosecondi in questo test sintetico perché la concatenazione di stringhe è del tutto evitata - un caso raro), ma in un codice di utilità altamente ottimizzato potrebbe essere un fattore. In ogni caso la risposta alla domanda originale è sì, potrebbe migliorare le prestazioni, ma marginalmente nella migliore delle ipotesi .

A parte i vantaggi della compilazione, non sono riuscito a trovare prove del fatto che l'uso della parola chiave finalabbia alcun effetto misurabile sulle prestazioni.


2
Ho riscritto un po 'il tuo codice per testare entrambi i casi 100 volte. Alla fine il tempo medio della finale è stato di 0 ms e 9 ms per la non finale. Aumentando il conteggio delle iterazioni a 10M, impostare la media su 0 ms e 75 ms. Tuttavia, la migliore esecuzione per la non finale è stata di 0 ms. Forse è il VM che rileva i risultati che vengono semplicemente eliminati o qualcosa del genere? Non lo so, ma a prescindere, l'uso di final fa una differenza significativa.
Casper Færgemand,

5
Test errato. Test precedenti riscaldano la JVM e avvantaggiano le successive invocazioni di test. Riordina i test e vedi cosa succede. È necessario eseguire ciascun test nella propria istanza JVM.
Steve Kuo,

16
No, il test non è imperfetto, il riscaldamento è stato preso in considerazione. Il secondo test è PIÙ LENTO, non più veloce. Senza riscaldamento, il secondo test sarebbe ANCORA PIÙ LENTO.
Rustyx,

6
In testFinal () tutti i tempi hanno restituito lo stesso oggetto, dal pool di stringhe, poiché la concatenazione letterale di stringhe e stringhe finali viene valutata al momento della compilazione. testNonFinal () restituisce ogni volta un nuovo oggetto, questo spiega la differenza di velocità.
Anber

4
Cosa ti fa pensare che lo scenario non sia realistico? Stringla concatenazione è un'operazione molto più costosa dell'aggiunta Integers. Farlo staticamente (se possibile) è più efficiente, questo è ciò che mostra il test.
Rustyx,

62

Sì, può. Ecco un'istanza in cui final può migliorare le prestazioni:

La compilazione condizionale è una tecnica in cui le righe di codice non vengono compilate nel file di classe in base a una condizione particolare. Questo può essere usato per rimuovere tonnellate di codice di debug in una build di produzione.

considerare quanto segue:

public class ConditionalCompile {

  private final static boolean doSomething= false;

    if (doSomething) {
       // do first part. 
    }

    if (doSomething) {
     // do second part. 
    }

    if (doSomething) {     
      // do third part. 
    }

    if (doSomething) {
    // do finalization part. 
    }
}

Convertendo l'attributo doSomething in un attributo finale, hai detto al compilatore che ogni volta che vede doSomething, dovrebbe sostituirlo con false secondo le regole di sostituzione in fase di compilazione. Il primo passaggio del compilatore modifica il codice in qualcosa del genere:

public class ConditionalCompile {

  private final static boolean doSomething= false;

    if (false){
       // do first part. 
    }

    if (false){
     // do second part. 
    }

    if (false){
      // do third part. 
    }

    if (false){
    // do finalization part. 

    }
}

Una volta fatto ciò, il compilatore lo esamina di nuovo e vede che ci sono dichiarazioni irraggiungibili nel codice. Dato che stai lavorando con un compilatore di alta qualità, non gli piacciono tutti quei codici byte irraggiungibili. Quindi li rimuove e si finisce con questo:

public class ConditionalCompile {


  private final static boolean doSomething= false;

  public static void someMethodBetter( ) {

    // do first part. 

    // do second part. 

    // do third part. 

    // do finalization part. 

  }
}

riducendo così eventuali codici eccessivi o qualsiasi controllo condizionale non necessario.

Modifica: ad esempio, prendiamo il seguente codice:

public class Test {
    public static final void main(String[] args) {
        boolean x = false;
        if (x) {
            System.out.println("x");
        }
        final boolean y = false;
        if (y) {
            System.out.println("y");
        }
        if (false) {
            System.out.println("z");
        }
    }
}

Compilando questo codice con Java 8 e decompilandolo con javap -c Test.classotteniamo:

public class Test {
  public Test();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  public static final void main(java.lang.String[]);
    Code:
       0: iconst_0
       1: istore_1
       2: iload_1
       3: ifeq          14
       6: getstatic     #16                 // Field java/lang/System.out:Ljava/io/PrintStream;
       9: ldc           #22                 // String x
      11: invokevirtual #24                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      14: iconst_0
      15: istore_2
      16: return
}

Possiamo notare che il codice compilato include solo la variabile non finale x. Ciò dimostra che le variabili finali hanno un impatto sulle prestazioni, almeno per questo semplice caso.


1
@ ŁukaszLech L'ho imparato da un libro di Oreilly: Hardcore Java, nel loro capitolo riguardante la parola chiave finale.
mel3kings

15
Questo parla di ottimizzazione al momento della compilazione, significa che lo sviluppatore conosce il VALORE della variabile booleana finale al momento della compilazione, qual è l'intero punto di scrivere se si blocca al primo posto quindi per questo scenario in cui le IF-CONDIZIONI non sono necessarie e non stanno facendo alcun senso? A mio avviso, anche se ciò migliora le prestazioni, questo è in primo luogo un codice errato e può essere ottimizzato dallo sviluppatore stesso piuttosto che passare la responsabilità al compilatore e la domanda intende principalmente porre domande sui miglioramenti delle prestazioni nei normali codici in cui viene utilizzato final ha un senso programmatico.
Bhavesh Agarwal,

7
Il punto di ciò sarebbe aggiungere dichiarazioni di debug come indicato da mel3kings. È possibile capovolgere la variabile prima di una build di produzione (o configurarla negli script di build) e rimuovere automaticamente tutto quel codice quando viene creata la distribuzione.
Adam


16

Sono sorpreso che nessuno abbia effettivamente pubblicato del codice reale che è stato decompilato per dimostrare che c'è almeno qualche differenza minore.

Per questo il riferimento è stato testato contro javacla versione 8, 9e 10.

Supponiamo che questo metodo:

public static int test() {
    /* final */ Object left = new Object();
    Object right = new Object();

    return left.hashCode() + right.hashCode();
}

Compilando questo codice così com'è, produce esattamente lo stesso codice byte di quando finalsarebbe stato presente ( final Object left = new Object();).

Ma questo:

public static int test() {
    /* final */ int left = 11;
    int right = 12;
    return left + right;
}

produce:

   0: bipush        11
   2: istore_0
   3: bipush        12
   5: istore_1
   6: iload_0
   7: iload_1
   8: iadd
   9: ireturn

Lasciando finaldi essere presenti produce:

   0: bipush        12
   2: istore_1
   3: bipush        11
   5: iload_1
   6: iadd
   7: ireturn

Il codice è praticamente autoesplicativo, nel caso in cui sia presente una costante di tempo di compilazione, verrà caricato direttamente nello stack dell'operando (non verrà memorizzato nell'array di variabili locali come nell'esempio precedente tramite bipush 12; istore_0; iload_0) - che tipo di senso ha senso dal momento che nessuno può cambiarlo.

D'altra parte, perché nel secondo caso il compilatore non produce istore_0 ... iload_0è al di là di me, non è che lo slot 0sia usato in alcun modo (potrebbe ridurre l'array di variabili in questo modo, ma potrebbe mancare alcuni dettagli interni, non posso dillo per certo)

Sono stato sorpreso di vedere una tale ottimizzazione, considerando quanto i piccoli lo javacfanno. Come dovremmo sempre usare final? Non ho nemmeno intenzione di scrivere un JMHtest (cosa che volevo inizialmente), sono sicuro che il diff sia nell'ordine di ns(se possibile essere catturato). L'unico posto in cui questo potrebbe essere un problema è quando un metodo non può essere integrato a causa delle sue dimensioni (e la dichiarazione finalridurrebbe tale dimensione di alcuni byte).

Ci sono altre due finals che devono essere affrontate. Il primo è quando un metodo è final(da una JITprospettiva), tale metodo è monomorfo - e questi sono i più amati dai JVM.

Quindi ci sono finalvariabili di istanza (che devono essere impostate in ogni costruttore); questi sono importanti in quanto garantiranno un riferimento pubblicato correttamente, come toccato un po 'qui e anche specificato esattamente dal JLS.


Ho compilato il codice usando Java 8 (JDK 1.8.0_162) con le opzioni di debug ( javac -g FinalTest.java), javap -c FinalTest.classho decompilato il codice usando e non ho ottenuto gli stessi risultati (con final int left=12, ho ottenuto bipush 11; istore_0; bipush 12; istore_1; bipush 11; iload_1; iadd; ireturn). Quindi sì, il bytecode generato dipende da molti fattori ed è difficile dire se avere finalo meno un effetto sulle prestazioni. Tuttavia, poiché il bytecode è diverso, potrebbero esistere alcune differenze di prestazioni.
Julien Kronegg,


13

Stai davvero chiedendo di due (almeno) casi diversi:

  1. final per variabili locali
  2. final per metodi / classi

Jon Skeet ha già risposto 2). Circa 1):

Non penso che faccia la differenza; per le variabili locali, il compilatore può dedurre se la variabile è definitiva o meno (semplicemente controllando se è assegnata più di una volta). Quindi, se il compilatore voleva ottimizzare le variabili assegnate una sola volta, può farlo indipendentemente dal fatto che la variabile sia effettivamente dichiarata finalo meno.

final potrebbe fare la differenza per i campi protetti / di classe pubblica; lì è molto difficile per il compilatore scoprire se il campo viene impostato più di una volta, come potrebbe accadere da una classe diversa (che potrebbe anche non essere stata caricata). Ma anche allora la JVM potrebbe usare la tecnica descritta da Jon (ottimizza in modo ottimistico, ripristina se viene caricata una classe che cambia il campo).

In sintesi, non vedo alcun motivo per cui dovrebbe aiutare le prestazioni. Quindi è improbabile che questo tipo di micro-ottimizzazione sia di aiuto. Potresti provare a confrontarlo per essere sicuro, ma dubito che farà la differenza.

Modificare:

In realtà, secondo la risposta di Timo Westkämper, in alcuni casi final può migliorare le prestazioni per i campi di classe. Sono corretto.


Non penso che il compilatore possa controllare correttamente il numero di volte in cui viene assegnata una variabile locale: che dire delle strutture if-then-else con numerose assegnazioni?
Gyorgyabraham,

1
@gyabraham: il compilatore controlla già questi casi se si dichiara una variabile locale come final, per assicurarsi di non assegnarla due volte. Per quanto posso vedere, la stessa logica di controllo può essere (e probabilmente viene) utilizzata per verificare se una variabile potrebbe essere final.
sleske,

Il carattere finale di una variabile locale non è espresso nel bytecode, quindi la JVM non sa nemmeno che era definitiva
Steve Kuo,

1
@SteveKuo: anche se non è espresso nel bytecode, può aiutare javaca ottimizzare meglio. Ma questa è solo una speculazione.
sleske,

1
Il compilatore potrebbe scoprire se una variabile locale è stata assegnata esattamente una volta, ma in pratica non lo fa (al di là del controllo degli errori). D'altra parte, se una finalvariabile è di un tipo o tipo primitivo Stringe viene immediatamente assegnata con una costante di compilazione come nell'esempio della domanda, il compilatore deve incorporarla, poiché la variabile è una costante di compilazione per specifica. Ma per la maggior parte dei casi d'uso, il codice potrebbe apparire diverso, ma non fa ancora alcuna differenza se la costante è incorporata o letta da una variabile locale dal punto di vista delle prestazioni.
Holger,

6

Nota: non un esperto di Java

Se ricordo correttamente il mio java, ci sarebbe pochissimo modo per migliorare le prestazioni usando la parola chiave finale. Ho sempre saputo che esistesse per "buon codice": design e leggibilità.


1

Non sono un esperto, ma suppongo che dovresti aggiungere una finalparola chiave alla classe o al metodo se non viene sovrascritto e lascia da sole le variabili. Se ci sarà un modo per ottimizzare tali cose, il compilatore lo farà per te.


1

In realtà, durante il test del codice relativo a OpenGL, ho scoperto che l'uso del modificatore finale su un campo privato può degradare le prestazioni. Ecco l'inizio della classe che ho testato:

public class ShaderInput {

    private /* final */ float[] input;
    private /* final */ int[] strides;


    public ShaderInput()
    {
        this.input = new float[10];
        this.strides = new int[] { 0, 4, 8 };
    }


    public ShaderInput x(int stride, float val)
    {
        input[strides[stride] + 0] = val;
        return this;
    }

    // more stuff ...

E questo è il metodo che ho usato per testare le prestazioni di varie alternative, tra cui la classe ShaderInput:

public static void test4()
{
    int arraySize = 10;
    float[] fb = new float[arraySize];
    for (int i = 0; i < arraySize; i++) {
        fb[i] = random.nextFloat();
    }
    int times = 1000000000;
    for (int i = 0; i < 10; ++i) {
        floatVectorTest(times, fb);
        arrayCopyTest(times, fb);
        shaderInputTest(times, fb);
        directFloatArrayTest(times, fb);
        System.out.println();
        System.gc();
    }
}

Dopo la terza iterazione, con il riscaldamento della VM, ho ottenuto costantemente queste cifre senza l'ultima parola chiave:

Simple array copy took   : 02.64
System.arrayCopy took    : 03.20
ShaderInput took         : 00.77
Unsafe float array took  : 05.47

Con la parola chiave finale:

Simple array copy took   : 02.66
System.arrayCopy took    : 03.20
ShaderInput took         : 02.59
Unsafe float array took  : 06.24

Nota le figure per il test ShaderInput.

Non importava se rendessi i campi pubblici o privati.

Per inciso, ci sono alcune altre cose sconcertanti. La classe ShaderInput supera tutte le altre varianti, anche con la parola chiave finale. Questo è notevole b / c, fondamentalmente è una classe che avvolge un array float, mentre gli altri test manipolano direttamente l'array. Devo capirlo. Potrebbe avere qualcosa a che fare con l'interfaccia fluente di ShaderInput.

Anche System.arrayCopy sembra effettivamente un po 'più lento per array di piccole dimensioni rispetto alla semplice copia di elementi da un array all'altro in un ciclo for. E usando sun.misc.Unsafe (così come java.nio.FloatBuffer diretto, non mostrato qui) si esibisce in modo abissale.


1
Hai dimenticato di rendere definitivi i parametri. <pre> <code> public ShaderInput x (passo int finale, valore float finale) {input [strides [stride] + 0] = val; restituire questo; } </code> </pre> Nelle mie esperienze, fare qualsiasi variabile o finale di campo può davvero migliorare le prestazioni.
Anticro,

1
Oh, e rendi anche gli altri finali: <pre> <code> final int arraySize = 10; final float [] fb = new float [arraySize]; for (int i = 0; i <arraySize; i ++) {fb [i] = random.nextFloat (); } final int times = 1000000000; per (int i = 0; i <10; ++ i) {floatVectorTest (times, fb); arrayCopyTest (times, fb); shaderInputTest (times, fb); directFloatArrayTest (times, fb); System.out.println (); System.gc (); } </code> </pre>
Anticro,

1

Il finale (almeno per le variabili e i parametri dei membri) è più per gli umani che per la macchina.

È buona norma rendere le variabili definitive ove possibile. Vorrei che Java avesse reso definitive le "variabili" e che avesse una parola chiave "mutabile" per consentire le modifiche. Le classi immutabili portano a un codice thread molto migliore, e basta dare un'occhiata a una classe con "final" davanti a ciascun membro mostrerà rapidamente che è immutabile.

Un altro caso: sto convertendo un sacco di codice per usare le annotazioni @ NonNull / @ Nullable (puoi dire che un parametro del metodo non deve essere nullo, quindi l'IDE può avvisarti ogni volta che passi una variabile che non è taggata @ NonNull - il tutto si diffonde in modo ridicolo). È molto più semplice dimostrare che una variabile o un parametro membro non può essere nullo quando è taggato come finale poiché sai che non viene assegnato nuovamente da nessun'altra parte.

Il mio suggerimento è prendere l'abitudine di applicare final per membri e parametri per impostazione predefinita, sono solo pochi caratteri ma ti spingeranno a migliorare il tuo stile di codifica se non altro.

Il finale per metodi o classi è un altro concetto in quanto non consente una forma molto valida di riutilizzo e non dice molto al lettore. Il miglior uso è probabilmente il modo in cui hanno reso String e gli altri tipi intrinseci finali in modo da poter fare affidamento su comportamenti coerenti ovunque - Ciò ha impedito un sacco di bug (anche se ci sono volte in cui mi sarebbe PIACIUTO AMARE ad estendere la stringa .... oh il possibilità)


0

Come menzionato altrove, "finale" per una variabile locale e, in misura leggermente minore, una variabile membro, è più una questione di stile.

'final' è un'affermazione in cui si intende che la variabile non cambi (ovvero, la variabile non varierà!). Il compilatore può quindi aiutarti lamentandoti in caso di violazione del proprio vincolo.

Condivido il sentimento secondo cui Java sarebbe stato un linguaggio migliore se gli identificatori (mi dispiace, non posso definire una variabile variabile una cosa non variabile) fossero predefiniti per impostazione predefinita e richiedessero di dire esplicitamente che erano variabili. Detto questo, in genere non uso "final" su variabili locali inizializzate e mai assegnate; sembra troppo rumoroso.

(Uso final sulle variabili membro)


-3

I membri dichiarati con final saranno disponibili in tutto il programma perché, a differenza di quelli non definitivi, se questi membri non fossero stati utilizzati nel programma, non verrebbero comunque curati da Garbage Collector, quindi potrebbero causare problemi di prestazioni a causa di una cattiva gestione della memoria.


2
Che tipo di assurdità è questa? Hai qualche fonte per cui pensi che sia così?
J. Doe,

-4

final la parola chiave può essere utilizzata in cinque modi in Java.

  1. Una lezione è definitiva
  2. Una variabile di riferimento è finale
  3. Una variabile locale è finale
  4. Un metodo è definitivo

Una classe è definitiva: una classe è definitiva significa che non possiamo essere estesi o ereditarietà significa che l'ereditarietà non è possibile.

Allo stesso modo - Un oggetto è definitivo: qualche volta non modificiamo lo stato interno dell'oggetto, quindi in tal caso possiamo specificare che l'oggetto è oggetto finale. Oggetto finale significa non variabile anche finale.

Una volta che la variabile di riferimento è resa definitiva, non può essere riassegnata ad altro oggetto. Ma può cambiare il contenuto dell'oggetto purché i suoi campi non siano definitivi


2
Con "oggetto è definitivo" intendi "l'oggetto è immutabile".
Gyorgyabraham,

6
Hai ragione, ma non stai rispondendo alla domanda. OP non ha chiesto cosa finalsignifichi, ma se l'utilizzo finalinfluenza la prestazione.
Honza Zidek,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.