Introduzione
Molti programmatori Java si chiedono se Java utilizzi il passaggio per valore o il passaggio per riferimento. Questo articolo riassume il motivo per cui Java è sempre basato sul passaggio per valore.
Per prima cosa, cosa significa passaggio per valore e passaggio per riferimento?
- Passaggio per valore: I valori dei parametri del metodo vengono copiati in un’altra variabile e poi l’oggetto copiato viene passato al metodo. Il metodo utilizza la copia.
- Passaggio per riferimento: Un alias o riferimento al parametro effettivo viene passato al metodo. Il metodo accede al parametro effettivo.
Spesso, la confusione su questi termini è il risultato del concetto di riferimento dell’oggetto in Java. Tecnicamente, Java è sempre basato sul passaggio per valore, perché anche se una variabile potrebbe contenere un riferimento a un oggetto, quel riferimento dell’oggetto è un valore che rappresenta la posizione dell’oggetto in memoria. I riferimenti agli oggetti vengono quindi passati per valore.
Sia i tipi di dati di riferimento che i tipi di dati primitivi vengono passati per valore. Per saperne di più sui tipi di dati in Java.
Oltre a comprendere i tipi di dati, è anche importante capire l’allocazione di memoria in Java, perché i tipi di dati di riferimento e i tipi di dati primitivi sono memorizzati in modo diverso.
Dimostrazione del passaggio per valore
L’esempio seguente mostra come vengono passati i valori in Java.
Il programma di esempio utilizza la seguente classe:
public class Balloon {
private String color;
public Balloon() {}
public Balloon(String c) {
this.color = c;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
Il programma di esempio seguente utilizza un metodo generico, swap()
, che scambia due variabili. Un altro metodo, changeValue()
, tenta di modificare i valori delle variabili.
public class Test {
public static void main(String[] args) {
Balloon red = new Balloon("Red"); // riferimento di memoria = 50
Balloon blue = new Balloon("Blue"); // riferimento di memoria = 100
swap(red, blue);
System.out.println("After the swap method executes:");
System.out.println("`red` color value = " + red.getColor());
System.out.println("`blue` color value = " + blue.getColor());
changeValue(blue);
System.out.println("After the changeValue method executes:");
System.out.println("`blue` color value = " + blue.getColor());
}
// Metodo di scambio generico
public static void swap(Object o1, Object o2){
Object temp = o1;
o1 = o2;
o2 = temp;
}
private static void changeValue(Balloon balloon) { // palloncino = 100
balloon.setColor("Red"); // palloncino = 100
balloon = new Balloon("Green"); // palloncino = 200
balloon.setColor("Blue"); // palloncino = 200
}
}
Quando si esegue il programma di esempio, si ottiene il seguente output:
OutputAfter the swap method executes:
'red' color value = Red
'blue' color value = Blue
After the changeValue method executes:
'blue' color value = Red
L’output mostra che il metodo swap()
non ha scambiato i valori dei colori degli oggetti originali. Ciò aiuta a dimostrare che Java è basato sul passaggio per valore, poiché il metodo swap()
agisce solo sulle copie dei valori di riferimento degli oggetti originali.
Questo test del metodo swap()
può essere utilizzato con qualsiasi linguaggio di programmazione per verificare se si tratta di un passaggio per valore o per riferimento.
Esempio del Metodo swap()
Spiegato
Quando si utilizza l’operatore new
per creare un’istanza di una classe, l’oggetto viene creato e la variabile contiene la posizione in memoria in cui l’oggetto è salvato.
Balloon red = new Balloon("Red");
Balloon blue = new Balloon("Blue");
Ecco una suddivisione passo dopo passo di ciò che accade quando il metodo swap()
viene eseguito:
-
Supponiamo che
red
punti alla posizione di memoria 50 eblue
punti alla posizione di memoria 100, e che queste siano le posizioni di memoria di entrambi gli oggettiBalloon
. -
Quando la classe chiama il metodo
swap()
con le variabilired
eblue
come argomenti, vengono create due nuove variabili di oggetto,o1
eo2
. Ancheo1
eo2
puntano alle posizioni di memoria 50 e 100 rispettivamente. -
Il seguente frammento di codice spiega cosa accade all’interno del metodo
swap()
:public static void swap(Object o1, Object o2) { // o1 = 50, o2 = 100 Object temp = o1; // assegna il valore di riferimento dell'oggetto di o1 a temp: temp = 50, o1 = 50, o2 = 100 o1 = o2; // assegna il valore di riferimento dell'oggetto di o2 a o1: temp = 50, o1 = 100, o2 = 100 o2 = temp; // assegna il valore di riferimento di temp a o2: temp = 50, o1 = 100, o2 = 50 } // termine del metodo
-
I valori di
o1
eo2
sono scambiati, ma poiché i valori sono copie delle posizioni di memoria dired
eblue
, non ci sono modifiche ai valori dei colorired
eblue
.
Dato che le variabili contengono il riferimento agli oggetti, è un errore comune assumere di passare il riferimento e che Java passi per riferimento. Tuttavia, si passa un valore che è una copia del riferimento e quindi si passa per valore.
Il Metodo di Esempio changeValue()
Spiegato
Il metodo successivo nell’esempio del programma cambia il valore del colore dell’oggetto referenziato dalla variabile blue
:
private static void changeValue(Balloon balloon) { // palloncino = 100
balloon.setColor("Red"); // palloncino = 100
balloon = new Balloon("Green"); // palloncino = 200
balloon.setColor("Blue"); // palloncino = 200
}
Ecco una spiegazione passo passo di cosa succede all’interno del metodo changeValue()
:
-
La classe chiama il metodo
changeValue()
sulla variabileblue
che fa riferimento alla posizione di memoria 100. La prima riga crea un riferimento che punta anche alla posizione di memoria 100. Il valore del colore dell’oggetto nella posizione di memoria 100 viene cambiato in"Rosso"
. -
La seconda riga crea un nuovo oggetto (con valore di colore
"Verde"
). Il nuovo oggetto si trova nella posizione di memoria 200. Eventuali metodi ulteriori eseguiti sulla variabilepalloncino
agiscono sull’oggetto nella posizione di memoria 200, e non influenzano l’oggetto nella posizione di memoria 100. La nuova variabilepalloncino
sovrascrive il riferimento creato nella riga 1 e il riferimento apalloncino
dalla riga 1 non è più accessibile all’interno di questo metodo. -
La terza riga cambia il valore del colore del nuovo oggetto
Balloon
nella posizione di memoria 200 in"Blue"
, ma non influisce sull’oggetto originale referenziato dablue
nella posizione di memoria 100. Questo spiega perché l’ultima riga dell’output del programma di esempio stampablue color value = Red
, che riflette il cambiamento dalla riga 1.
Conclusione
In questo articolo hai appreso perché Java è passato per valore. Continua il tuo apprendimento con altri tutorial Java.
Source:
https://www.digitalocean.com/community/tutorials/java-is-pass-by-value-and-not-pass-by-reference