In Java viene sempre utilizzato il meccanismo pass-by-value (passaggio per valore), ma c'è una particolarità per gli oggetti:
Pertanto, la modifica dei campi dell'oggetto all'interno del metodo si riflette sull'oggetto originale, mentre il tentativo di assegnare un nuovo riferimento alla variabile all'interno del metodo non influisce sull'oggetto originale. Questo è spesso confuso con pass-by-reference, ma Java non supporta il pass-by-reference!
Esempio:
void changePrimitive(int a) { a = 10; } void changeObject(Point p) { p.x = 10; } int num = 5; changePrimitive(num); // num è ancora 5 Point pt = new Point(1, 2); changeObject(pt); // ora pt.x == 10
Importante! Se all'interno del metodo viene assegnato p = new Point(100, 200), l'oggetto originale al di fuori del metodo non cambierà. Cambia il campo dell'oggetto, non il suo riferimento!
Domanda: È possibile all'interno di un metodo cambiare un oggetto passato come argomento, in modo che al di fuori del metodo la variabile-riferimento punti a un nuovo oggetto?
Risposta: No, non è possibile. Assegnando un nuovo riferimento all'argomento all'interno del metodo, si influisce solo su una copia del riferimento, che scompare dopo l'uscita dal metodo. Al di fuori del metodo, la variabile-argomento punta all'oggetto precedente.
void reassign(Point p) { p = new Point(100, 200); // solo localmente! } Point pt = new Point(5, 5); reassign(pt); // pt è ancora (5, 5)
Storia
In un grande sistema finanziario è stato implementato un'API che "restituiva" modifiche all'oggetto, modificando il riferimento all'interno del metodo. Di conseguenza, dopo l'uscita dal metodo, le modifiche non si riflettevano. È stato necessario riprogettare completamente una parte della logica per chiarire la distinzione tra mutazione e restituzione di nuovi oggetti.
Storia
Durante il tentativo di implementare lo swap di due oggetti in Java con il metodo
swap(A a, B b), lo sviluppatore passava i riferimenti e li scambiava all'interno del metodo. Non ha funzionato. È necessario restituire il risultato o utilizzare contenitori-array. La mancanza di conoscenza del pass-by-value ha portato a uno scambio errato di oggetti.
Storia
Uno dei partecipanti al progetto ha migrato la logica da C++ e si aspettava un comportamento di pass-by-reference. Di conseguenza, i metodi hanno smesso di funzionare correttamente: le modifiche all'interno del metodo non "uscivano" all'esterno. È stato necessario riscrivere urgentemente parti critiche del codice, il che ha richiesto tempo significativo.