ProgrammazioneSviluppatore Backend

Come funziona il meccanismo di passaggio dei parametri nei metodi Java (pass-by-value) e come può differire da altri linguaggi di programmazione?

Supera i colloqui con l'assistente IA Hintsage

Risposta

In Java viene sempre utilizzato il meccanismo pass-by-value (passaggio per valore), ma c'è una particolarità per gli oggetti:

  • Per i tipi primitivi viene coperto il valore stesso.
  • Per gli oggetti viene copiata la valore del riferimento all'oggetto, ma non l'oggetto stesso.

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 trabocchetto

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)

Esempi di errori reali dovuti alla mancanza di conoscenza delle sfumature dell'argomento


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.