Spesso si legge di oggetti immutabili che richiedono che i campi finali siano immutabili in Java. È questo il caso, o è semplicemente sufficiente per non avere mutabilità pubblica e non mutare effettivamente lo stato?I campi devono essere esplicitamente definitivi per avere un oggetto "corretto" immutabile?
Ad esempio, se si dispone di un oggetto immutabile creato dal modello di builder, è possibile farlo assegnando al builder i singoli campi mentre vengono creati, oppure mantenendo il campo stesso e restituendo infine l'oggetto immutabile passando i valori al suo costruttore (privato).
Avere i campi finali ha l'ovvio vantaggio di impedire errori di implementazione (come ad esempio consentire al codice di conservare un riferimento al builder e "costruire" l'oggetto più volte mentre in realtà muta un oggetto esistente), ma avendo l'archivio Builder i suoi dati all'interno dell'oggetto così come sono costruiti sembrano essere DRYer.
Quindi la domanda è: supponendo che il Builder non perda l'oggetto in anticipo e si fermi da modificare l'oggetto una volta costruito (ad esempio impostando il suo riferimento all'oggetto come null) ci sia effettivamente qualcosa ottenuto (come una migliore sicurezza del thread) nella "immutabilità" dell'oggetto se invece i campi dell'oggetto sono stati resi definitivi?
Se non sbaglio * final * può anche aiutare a prevenire gli "attacchi di riflessione" in cui un programmatore canaglia usa la riflessione per accedere ai campi della classe e modificare il loro contenuto. C'era un famoso esempio che pervertiva completamente la classe * String * e mostrava che in molti casi * String * poteva essere effettivamente modificato (se non fosse dovuto a non-finalness btw ma a causa del fatto che una volta il sottostante * char [] * è stato utilizzato se era "game over" perché non si può forzare l'immutabilità sul contenuto di una matrice ... Ma non è questo il mio punto: il mio punto è che la riflessione può aiutare a fare cose davvero cattive). – TacticalCoder
@user, di fronte a una riflessione del genere, non è possibile stabilire l'immutabilità. Tuttavia, il Security Manager sta facendo funzionare il codice di terze parti come tale. – Yishai
wait ... Se ho una * final * class avente un * int finale unico * è possibile modificarlo usando il reflection? Il punto era proprio che * senza * usando * final * non si può prevenire contro gli attacchi di reflection (a meno che non si abbia un * Security Manager * in posizione, ma non è quasi mai il caso, motivo per cui ho scritto * "in molti casi può essere modificato "* ...). Tuttavia non sono sicuro che tu possa usare il reflection per modificare un * final int * ... Se non puoi, allora il mio commento è abbastanza in discussione con la tua domanda:) (Ho fatto +1 la tua domanda ieri btw:) – TacticalCoder