Java est passé par valeur, pas par référence

Introduction

De nombreux programmeurs Java se demandent si Java est passé par valeur ou passé par référence. Cet article résume pourquoi Java est toujours passé par valeur.

Tout d’abord, que signifient « passé par valeur » et « passé par référence » ?

  • Passé par valeur : Les valeurs des paramètres de la méthode sont copiées dans une autre variable, puis l’objet copié est passé à la méthode. La méthode utilise la copie.
  • Passé par référence : Un alias ou une référence du paramètre réel est passé à la méthode. La méthode accède au paramètre réel.

Souvent, la confusion autour de ces termes résulte du concept de référence d’objet en Java. Techniquement, Java est toujours passé par valeur, car même si une variable peut contenir une référence à un objet, cette référence d’objet est une valeur qui représente l’emplacement de l’objet en mémoire. Les références d’objet sont donc passées par valeur.

Les types de données de référence et les types de données primitifs sont tous deux passés par valeur. Apprenez-en davantage sur les types de données en Java.

En plus de comprendre les types de données, il est également important de comprendre l’allocation de mémoire en Java, car les types de données de référence et les types de données primitifs sont stockés différemment.

Démonstration du passage par valeur

L’exemple suivant montre comment les valeurs sont transmises en Java.

Le programme d’exemple utilise la classe suivante :

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;
	}
}

Le programme d’exemple suivant utilise une méthode générique, swap(), qui échange deux variables. Une autre méthode, changeValue(), tente de modifier les valeurs des variables.

public class Test {

	public static void main(String[] args) {

		Balloon red = new Balloon("Red"); // référence mémoire = 50
		Balloon blue = new Balloon("Blue"); // référence mémoire = 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());
		
	}

	// Méthode générique d'échange
	public static void swap(Object o1, Object o2){
		Object temp = o1;
		o1 = o2;
		o2 = temp;
	}

	private static void changeValue(Balloon balloon) { // ballon = 100
		balloon.setColor("Red"); // ballon = 100
		balloon = new Balloon("Green"); // ballon = 200
		balloon.setColor("Blue"); // ballon = 200
	}

}

Lorsque vous exécutez le programme d’exemple, vous obtenez la sortie suivante :

Output
After the swap method executes: 'red' color value = Red 'blue' color value = Blue After the changeValue method executes: 'blue' color value = Red

La sortie montre que la méthode swap() n’a pas échangé les valeurs de couleur des objets d’origine. Cela aide à démontrer que Java utilise le passage par valeur, car la méthode swap() agit uniquement sur des copies des valeurs de référence d’objet d’origine.

Ce test de méthode swap() peut être utilisé avec n’importe quel langage de programmation pour vérifier s’il s’agit d’un passage par valeur ou par référence.

L’exemple de la méthode swap() expliqué

Quand vous utilisez l’opérateur new pour créer une instance d’une classe, l’objet est créé et la variable contient l’emplacement en mémoire où l’objet est enregistré.

Balloon red = new Balloon("Red");
Balloon blue = new Balloon("Blue");

Voici une explication étape par étape de ce qui se passe lorsque la méthode swap() s’exécute :

  • Supposons que red pointe vers l’emplacement mémoire 50 et que blue pointe vers l’emplacement mémoire 100, et que ce sont les emplacements mémoire des objets Balloon.

  • Lorsque la classe appelle la méthode swap() avec les variables red et blue comme arguments, deux nouvelles variables d’objet, o1 et o2, sont créées. o1 et o2 pointent également vers les emplacements mémoire 50 et 100 respectivement.

  • Le code suivant explique ce qui se passe à l’intérieur de la méthode swap():

    public static void swap(Object o1, Object o2) { // o1 = 50, o2 = 100
    	Object temp = o1; // attribue la valeur de référence de l'objet o1 à temp : temp = 50, o1 = 50, o2 = 100
    	o1 = o2; // attribue la valeur de référence de l'objet o2 à o1 : temp = 50, o1 = 100, o2 = 100
    	o2 = temp; // attribue la valeur de référence de temp à o2 : temp = 50, o1 = 100, o2 = 50
    } // méthode terminée
    
  • Les valeurs de o1 et o2 sont échangées, mais parce que les valeurs sont des copies des emplacements mémoire red et blue, il n’y a pas de changement dans les valeurs des couleurs red et blue.

Étant donné que les variables contiennent la référence aux objets, il est courant de supposer que vous transmettez la référence et que Java fonctionne en passant par référence. Cependant, vous transmettez une valeur qui est une copie de la référence et donc c’est un passage par valeur.

L’exemple de la méthode changeValue() expliqué

La méthode suivante dans le programme d’exemple change la valeur de couleur de l’objet référencé par la variable blue:

private static void changeValue(Balloon balloon) { // ballon = 100
	balloon.setColor("Red"); // ballon = 100
	balloon = new Balloon("Green"); // ballon = 200
	balloon.setColor("Blue"); // ballon = 200
}

Voici une analyse étape par étape de ce qui se passe dans la méthode changeValue():

  • La classe appelle la méthode changeValue() sur la variable blue qui référence l’emplacement mémoire 100. La première ligne crée une référence qui pointe également vers l’emplacement mémoire 100. La valeur de couleur de l’objet à l’emplacement mémoire 100 est changée en "Rouge".

  • La deuxième ligne crée un nouvel objet (avec une valeur de couleur "Vert"). Le nouvel objet est à l’emplacement mémoire 200. Toutes les méthodes ultérieures exécutées sur la variable ballon agissent sur l’objet à l’emplacement mémoire 200 et n’affectent pas l’objet à l’emplacement mémoire 100. La nouvelle variable ballon écrase la référence créée à la ligne 1 et la référence ballon de la ligne 1 n’est plus accessible dans cette méthode.

  • La troisième ligne change la valeur de couleur du nouvel objet Balloon à l’emplacement mémoire 200 en "Bleu", mais n’affecte pas l’objet original référencé par blue à l’emplacement mémoire 100. Cela explique pourquoi la dernière ligne de la sortie du programme exemple affiche blue color value = Red, ce qui reflète le changement de la ligne 1.

Conclusion

Dans cet article, vous avez appris pourquoi Java est passé par valeur. Poursuivez votre apprentissage avec plus de tutoriels Java.

Source:
https://www.digitalocean.com/community/tutorials/java-is-pass-by-value-and-not-pass-by-reference