Java passe-t-il vraiment des objets par valeur? [dupliquer]
Double Possible: est Java pass par référence?
public class myClass{
public static void main(String[] args){
myObject obj = new myObject("myName");
changeName(obj);
System.out.print(obj.getName()); // This prints "anotherName"
}
public static void changeName(myObject obj){
obj.setName("anotherName");
}
}
je sais que Java passage par valeur, mais pourquoi faut-il passer obj
par référence dans l'exemple précédent, et de les modifier?
6 réponses
Java passe toujours les arguments par valeur, pas par référence. Dans votre exemple, vous passez encore obj
par sa valeur, pas la référence elle-même. Dans votre méthode changeName
, vous assignez une autre référence (locale), obj
, au même objet que vous lui avez passé comme argument. Une fois que vous avez modifié cette référence, vous modifiez la référence originale, obj
, qui est passée en argument.
EDIT:
permettez-moi de l'expliquer par un exemple:
public class Main
{
public static void main(String[] args)
{
Foo f = new Foo("f");
changeReference(f); // It won't change the reference!
modifyReference(f); // It will change the object that the reference refers to!
}
public static void changeReference(Foo a)
{
Foo b = new Foo("b");
a = b;
}
public static void modifyReference(Foo c)
{
c.setAttribute("c");
}
}
je vais vous expliquer ceci par étapes:
1-déclarer une référence nommée f
de type Foo
et l'attribuer à un nouvel objet de type Foo
avec un attribut "f"
.
Foo f = new Foo("f");
2-du côté de la méthode, une référence de type Foo
avec un nom a
est déclaré et il est initialement assigné à null
.
public static void changeReference(Foo a)
3-comme vous appelez la méthode changeReference
, la référence a
sera assignée à l'objet qui est passé comme argument.
changeReference(f);
4-déclarant une référence nommée b
de tapez Foo
et l'attribuer à un nouvel objet de type Foo
avec un attribut "b"
.
Foo b = new Foo("b");
5- a = b
renvoie la référence a
et non f
à l'objet dont l'attribut est "b"
.
6- comme vous appelez modifyReference(Foo c)
méthode, un la référence c
est créée et assignée à l'objet avec l'attribut "f"
.
7 - c.setAttribute("c");
va changer l'attribut de l'objet qui se réfère c
points à elle, et c'est le même objet qui se réfère f
points à elle.
j'espère que vous comprenez maintenant comment passer des objets comme arguments fonctionne en Java:)
en Java, un objet handle, ou l'identité d'un objet est considéré comme une valeur. Passer par la valeur signifie passer cette poignée, pas une copie complète de l'objet.
Une "référence" dans le terme "passage par référence" ne signifie pas non plus "référence à un objet". Il signifie "référence à une variable "– un" seau " nommé dans une définition de fonction (ou, plutôt, un cadre d'appel) qui peut stocker une valeur.
passer par référence signifierait que la méthode appelée pourrait changer valeurs variables dans la méthode d'appel. (Par exemple, dans la bibliothèque standard C, la fonction scanf
fonctionne de cette façon.) Ce n'est pas possible en Java. Vous pouvez toujours modifier les propriétés d'un objet – elles ne sont pas considérées comme faisant partie de sa" valeur". Ce sont des objets indépendants complètement différents.
vous changez une propriété de obj
, ne changeant pas obj
(le paramètre) lui-même.
le point est que si vous pointez obj
à quelque chose d'autre dans changeName
que que changement ne se refléterait pas dans main
.
Voir ce post pour plus de précisions.
il n'a pas changé obj (votre code ne le change pas de toute façon). Si elle avait été transmise par référence, vous auriez pu écrire:
public static void changeName(myObject obj){
obj = new myObject("anotherName");
}
et avoir" un autre nom " imprimé par la méthode principale.
Java transmet une copie de ce que vous transmettez à votre fonction. Quand c'est un type primitif, il sera la copie d'une valeur. Quand c'est un objet - vous passez la copie de référence. Dans votre exemple de code, vous modifiez l'une des propriétés des objets, mais pas la référence elle-même, de sorte que le nom sera modifié. Cependant, lorsque vous souhaitez assigner un nouvel objet à une variable obj dans la fonction changeName, alors vous changez la référence, donc hors obj aura une ancienne valeur.
il passe la référence à obj comme une valeur (un peu confus je sais :)).
donc disons qu'il fait une copie du pointeur à la valeur d'obj et passer cela.
cela signifie que vous pouvez faire des choses comme:
public static void changeName(myObject obj){
obj.setName("anotherName");
obj = new myObject();
}
et la mention
System.out.print(obj.getName());
va toujours se référer à l'ancien objet (celui que vous avez fait setName).