2010-01-13 21 views
11

qual è il punto di avere una variabile di istanza come finale?punto di avere una variabile di istanza come finale?

non è meglio avere quella variabile impostata come variabile finale statica?

causa se non può essere modificato da nessuno degli oggetti, quindi è la stessa di una variabile di classe (statica), giusto?

+0

http://renaud.waldura.com/doc/java/final-keyword.shtml –

risposta

20

Nope. static significa che è uguale per tutte le istanze della classe. final significa che non è assegnabile dopo il suo incarico iniziale. Quindi due istanze potrebbero avere valori diversi per una variabile finale non statica.

Ci sono molte ragioni per cui si potrebbe voler rendere una variabile finale; uno dei migliori è la chiarezza. Se leggo un metodo e noto che il foo è definitivo, non devo preoccuparmi di dove sta cambiando in basso - perché non lo è; non può Posso apportare più modifiche al codice con variabili finali con meno preoccupazione ("ho cambiato il valore di foo prima o dopo la barra, e ha importanza?") Perché so che alcune variabili non sono soggette a modifiche. Si concentra anche la mia attenzione sulle variabili che sono soggette a modifiche - e sono quelle che meritano più attenzione.

+1

ma non si assegna un valore alla variabile di istanza finale quando si scrive la classe? allora questo significa che tutti gli oggetti useranno quel valore e non possono cambiare? o mi sbaglio? – ajsie

+5

Non necessariamente - può essere assegnato nel costruttore. – danben

1

Previene altri programmatori di fare cose stupide che non dovrebbero provare a fare comunque ...

2

È possibile assegnare un valore specifico all'istanza dell'oggetto, che non è possibile eseguire con una variabile di classe statica.

+0

quindi intendi quando scrivo la classe, la dichiaro solo come definitiva. e quando ho istanziato la classe e chiamato un metodo, il metodo assegnerà un valore ad esso che non può essere modificato? – ajsie

+0

Penso che sia necessario assegnare un valore nel costruttore, altrimenti il ​​compilatore genererà un errore. –

3

due motivi:

1) Dal punto di vista di design di classe, che permette ai programmatori di fare affidamento sul fatto che il campo non cambierà in quanto esemplificazione - cosiddetta "immutable object". Esercitazione Java dice:

Gli oggetti immutabili sono particolarmente utili in applicazioni concorrenti. Dal momento che non possono cambiare lo stato, non possono essere corrotti dall'interferenza del filo o osservati in uno stato incoerente.

Gli oggetti immutabili sono una pietra angolare di vari stili di programmazione, ad es. pura programmazione funzionale.

2) Il secondo motivo sono le ottimizzazioni JVM. Se tutti i campi sono definitivi, JVM sa che lo stato dell'oggetto non può essere modificato e quindi può apportare molte ottimizzazioni, ad es. ommiting controlli di sicurezza del filo ecc.

+1

@Ondra - il fatto che la JVM * potrebbe * (o potrebbe non) ottimizzare i campi 'final', ecc. È un problema secondario. La motivazione principale per l'utilizzo di 'final' dovrebbe essere quella di rendere il codice più solido. (E ricorda il consiglio che è una cattiva idea ottimizzare micro in Java perché il compilatore JIT può fare un lavoro migliore se non lo fai!) –

+0

@Stephen: 1) Ho coperto l'aspetto "robusto" del finale in il secondo paragrafo. 2) Rendere immutabile il tuo piccolo oggetto di dati non è sicuramente una microottimizzazione - può fornire significativi aumenti di prestazioni. "Uno dei motivi più comuni dati per non rendere immutabile una classe è la convinzione che fare ciò comprometterebbe le prestazioni. Anche se questo è vero a volte, spesso non lo è - e a volte l'uso di oggetti immutabili è significativo, e forse sorprendenti, vantaggi prestazionali. " –

4

immagino che stai pensando di caso semplice come ad esempio:

private final int num = 3; 

Che può essere meglio scritto come:

private static final int NUM = 3; 

Tuttavia, spesso si dovrà riferimenti a oggetti che sono mutevoli, e quindi non può essere condiviso tra le classi:

private final List<Node> children = new ArrayList<Children>(); 

O forse, un valore passato in o derivati ​​nei costruttori:

public final class MyThing { 
     private final String name; 
     public MyThing(String name) { 
      this.name = name; 
     } 
     [...] 
} 

Nota: final campi possono essere assegnati nei costruttori (o istanza initialiser), non solo come parte della dichiarazione.

+0

Il tuo ultimo esempio mostra una classe 'final'. Ciò non ha nulla a che fare con la mutabilità e confonderà solo il lettore principiante. –

Problemi correlati