Contrairement à certains termes courants, Java passe tout par valeur. Même lorsque nous travaillons avec des objets, ce que nous passons en réalité est la valeur de la référence à l’objet, pas l’objet lui-même.
Références en Java, des pointeurs déguisés
Considérons la déclaration :
d = new Dog("Fifi");
Il est crucial de comprendre que myDog n’est pas un objet Dog; c’est essentiellement un pointeur vers un Dog. Cela signifie que lorsque vous créez un objet :
Dog myDog = new Dog("Rover");
Vous passez en réalité l’adresse du nouvel objet Dog à toute méthode prenant myDog en paramètre. Bien que les pointeurs Java ne représentent pas directement les adresses mémoire, les considérer de cette manière simplifie la compréhension.
Explorons un exemple de méthode :
public class TestObject{
public static void main(String ... args) {
Dog myDog = new Dog("Rover");
foo(myDog);
System.out.println(myDog.getName());//5
}
public void foo(Dog someDog) { // 1
someDog.setName("Max"); // 2
someDog = new Dog("Fifi"); // 3
someDog.setName("Rowlf"); // 4
}
}
- À la ligne 1,
someDogest défini sur la valeur 3333 (en supposant que l’objetmyDogest à l’adresse mémoire 3333). - À la ligne 2,
someDogest suivi jusqu’auDogqu’il pointe (l’objetDogà l’adresse 3333), et ceDogest invité à changer son nom en “Max”. - À la ligne 3, un nouveau
Dogest créé à l’adresse 4444, etsomeDogest maintenant assigné à cette adresse (4444). - À la ligne 4,
someDogest suivi jusqu’auDogqu’il pointe (l’objetDogà l’adresse 4444), et ceDogest invité à changer son nom en “Rowlf”.
Maintenant, considérons ce qui se passe en dehors de la méthode : La question est, myDog a-t-il changé ?
La réponse réside dans le fait de se rappeler que myDog est un pointeur, pas l’objet Dog lui-même. La réponse est NON. myDog a toujours la valeur 3333 ; il pointe toujours vers l’objet Dog d’origine.
A la ligne 5, c’est donc bien “Max” qui sera affiché comme nom de chien.
Pour approfondir ce sujet je vous invite à consulter cet article.
Considerons l’exemple ci dessous :
Que se passe t-il si on affecte une référence null à un paramètre?
public class TestObject{
public static void main(String ... args) {
Dog myDog = new Dog("Rover");
foo(myDog);
System.out.println(myDog.getName());
}
public void foo(Dog someDog) {//1
someDog = null;//2
}
}
Cet exemple est très similaire au précedent. Je vous epargne l’explication des différentes étapes.
A votre avis quel resultat produira ce code?
D’aucun serait tenté de dire que ce code produira une exception de type NullpointerException. En réalité il n’en est rien.
Souvenez vous someDog est défini sur une valeur precise (par exemple 3333). La méthode foo ne modifie pas someDog.
En effet à la ligne //1 someDog et myDog pointe tous les deux sur l’adresse 3333.
A la ligne //2, nous faisons pointer someDog sur la reference nulle (une variable special en java). Mais myDog pointe toujours sur 3333.
