final
dichiara un riferimento oggetto che non può essere modificato, ad es.
private final Foo something = new Foo();
crea un nuovo Foo
e pone il riferimento in something
.Successivamente, non è possibile modificare something
in modo che punti a un'altra istanza di Foo
.
Questo non impedisce la modifica dello stato interno dell'oggetto. Posso ancora chiamare qualsiasi metodo su Foo
, sono accessibili per l'ambito pertinente. Se uno o più di questi metodi modifica lo stato interno di quell'oggetto, allora final
non lo impedirà.
Come tale, il seguente:
private final Set<String> fixed = new HashSet<String>();
fa non creare un Set
che non può essere inserito o altrimenti alterato; significa semplicemente che fixed
farà sempre riferimento a tale istanza.
Al contrario, facendo:
private Set<String> fixed = Collections.unmodifiableSet(new HashSet<String>());
crea un'istanza di un Set
, che getterà UnsupportedOperationException
se si cerca di chiamare fixed.add()
o fixed.remove()
, per esempio - l'oggetto stesso proteggerà il suo stato interno ed evitare che si essere modificato.
Per completezza:
private final Set<String> fixed = Collections.unmodifiableSet(new HashSet<String>());
crea un'istanza di un Set
che non consente il suo stato interno di essere cambiato, e significa anche che fixed
sarà sempre solo puntare a un'istanza di tale insieme.
Il motivo per cui final
può essere utilizzato per creare costanti di primitive si basa sul fatto che il valore non può essere modificato. Ricorda che fixed
sopra era solo un riferimento - una variabile contenente un indirizzo che non può essere modificato. Bene, per i primitivi, ad es.
private final int ANSWER = 42;
il valore di ANSWER
è che ANSWER
42. Poiché non può essere modificato, sarà sempre e solo avere il valore 42.
Un esempio che confonde tutte le linee sarebbe questo:
private final String QUESTION = "The ultimate question";
Per le regole precedenti, QUESTION
contiene l'indirizzo di un'istanza di String
che rappresenta "La domanda finale" e che l'indirizzo non può essere modificato. La cosa da ricordare qui è che lo stesso String
è immutabile: non è possibile eseguire alcuna operazione su un'istanza di String
che lo modifica e qualsiasi operazione che altrimenti lo farebbe (come replace
, substring
, ecc.) Restituirà riferimenti completamente diversi istanze di String
.
Buon post. In breve, _reference_ non può essere modificato ma i _contents_ dell'oggetto * possono *. – extraneon