Java passa per riferimento?

Java supporta davvero il passaggio per riferimento?

In caso contrario, perché abbiamo l’operatore == per trovare due oggetti con lo stesso riferimento?

Java usa passare per valore, non per riferimento …

Ma, per i tipi non primitivi, il valore è il valore del riferimento.

Quindi == confronta i valori dei riferimenti per gli oggetti.

Per una spiegazione dettagliata, vedi il mio articolo “Java è Pass-By-Value, Dammit!”

http://javadude.com/articles/passbyvalue.htm

Il punto di distinzione è tra “pass ** – by- reference” e “ passing a ** reference”. A volte vedi anche “call-by -…” e “pass-by -…” usati in modo intercambiabile. Per semplicità, rimarrò con “pass-by -…”.

  1. Nella terminologia accademica, vecchia scuola, pertinente a FORTRAN, pass-per-riferimento significa che il codice chiamato ha accesso (riferimento) a una variabile passata dal chiamante. Assegnare al parametro formale nel codice chiamato esegue effettivamente un assegnamento alla variabile del chiamante. La distinzione è versus (tra gli altri) pass-by-value , che dà al codice chiamato una copia dei dati (qualunque essa sia) noti al chiamante.

  2. Nel moderno mondo OO pertinente a Java, “avere un riferimento” a un object significa essere in grado di raggiungere l’object stesso. Questo si distingue da “avere un puntatore” per enfatizzare (tra le altre cose) che non si fa “puntatore aritmetico” su un riferimento. (In effetti, un “riferimento” in questo senso non deve necessariamente essere un effettivo indirizzo di memoria simile a un puntatore.)

Java passa gli argomenti per valore (nel primo senso), ma per gli argomenti object, il valore è un riferimento (nel secondo senso). Ecco un po ‘di codice che si basa sulla differenza.

// called public void munge(List a0, List a1) { List foo = new List(); foo.add("everybody"); a0.set(0, "Goodbye"); a1 = foo; } // caller ... List l0 = new List(); l0.add("Hello"); List l1 = new List(); l1.add("world"); munge(l0, l1); ... 

Al ritorno da munge , la prima lista del chiamante, l0 conterrà "Goodbye" . Un riferimento a munge stato passato a munge , che ha chiamato un metodo di munge su munge . (In altre parole, a0 ricevuto una copia del valore di l0 , che era un riferimento a una lista di stringhe che è stata modificata).

Tuttavia, al ritorno da munge , la seconda lista del chiamante, l1 contiene ancora "world" perché non sono stati chiamati metodi sul riferimento dell’object passato (il valore di l1 , passato per valore a munge ). Invece, la variabile argomento a1 stata impostata su un nuovo valore (anche il riferimento all’object locale è contenuto in foo ).

Se Java avesse usato il pass-per-riferimento, al momento del ritorno, l1 avrebbe contenuto "everybody" perché a1 avrebbe fatto riferimento alla variabile l1 e non sarebbe stato semplicemente inizializzato su una copia del suo valore. Quindi il compito di a1 sarebbe stato anche un incarico a l1 .

Questo stesso problema è stato discusso in un’altra domanda , con l’arte ASCII per illustrare la situazione.

Java non usa il pass-by-reference ma piuttosto il pass-by-value. I parametri del valore primitivo vengono copiati nello stack, così come i puntatori agli oggetti.

L’operatore == dovrebbe essere usato per confrontare i valori primitivi e per confrontare i riferimenti agli oggetti.

La risposta breve è no. In Java esiste solo il valore pass-by e quando si lavora con oggetti (ad es. Object obj = new Object(); ), si sta lavorando con riferimenti a oggetti. Che vengono passati per valore.

Per i dettagli, vedere: Parametro che passa in Java