Gli oggetti possono essere immutabili e i riferimenti ad essi possono essere definitivi; ma il contrario è per lo più confusione tecnica. Un "oggetto finale" è in realtà un riferimento finale a un oggetto, mentre un "riferimento immutabile" (o "campo immutabile" o "variabile immutabile") viene raramente menzionato perché non è il modo in cui vengono considerati. Un riferimento è effettivamente un indirizzo, e quindi come un numero primitivo o booleano. Una variabile o campo può contenere il numero intero 10. Se si incrementa tale numero intero, si sta "mutando" quel 10 o si assegna realmente un numero intero diverso? A livello di bit, stai modificando il contenuto di una singola posizione di memoria, ma a livello di linguaggio semantico è quest'ultimo, poiché ovunque altro che utilizza 10 è invariato.
Un campo o variabile finale deve essere assegnato esattamente una volta e il compilatore lo farà rispettare. Un oggetto immutabile non cambia una volta completata la costruzione, ma non esiste una reale applicazione. Si noti che anche se si definisce un oggetto che ha solo campi finali, ciò non rende automaticamente l'oggetto immutabile. Se un campo finale è un riferimento a un oggetto, quell'oggetto nidificato deve essere immutabile. Non c'è nemmeno modo a livello di linguaggio per rendere immutabile una matrice; un riferimento finale a un array significa che non puoi cambiare la matrice o la sua lunghezza, ma puoi cambiarne il contenuto. Il linguaggio non può imporre di rendere tale oggetto immutabile. Quindi in molti casi, un oggetto è immutabile solo perché tu lo intendi (e se c'è un bug nel tuo codice, forse non lo è).
Gli oggetti
String
sono così: hanno una matrice di caratteri final
e sono immutabili solo perché i metodi che potrebbero cambiare qualcosa restituiscono invece altre istanze. Metodi come substring
possono effettivamente condividere l'array di caratteri originale e semplicemente "vedere" una sezione diversa di quell'array.