2009-02-26 5 views
10

Est-ce que Java supporte vraiment le passage par référence?Est-ce que Java passe par référence?

Si ce n'est pas le cas, pourquoi avons-nous l'opérateur == pour trouver deux objets avec la même référence?

+0

Appelez par référence et passez par référence sont la même chose, non? Sinon, quelqu'un peut revenir à la question. –

+0

Java prend en charge la copie des références (pas les références d'origine), de sorte que toute modification sur les références à l'intérieur de la méthode ne soit pas reflétée en dehors de celle-ci. Vérifiez ceci: [Java - passer par référence ou passer par valeur] (http://programmergate.com/java-pass-reference-pass-value/) –

Répondre

14

Java utilise passe par valeur, et non par référence ...

Mais, pour les types primitifs non la valeur est la valeur de la référence.

So == compare les valeurs des références pour les objets.

+0

Mais au niveau du byte-code il a une référence ... non? https://en.wikipedia.org/wiki/Java_bytecode –

3

Java n'utilise pas utilise la référence de passage, mais plutôt la valeur de transfert. Les paramètres de valeur primitive sont copiés dans la pile, ainsi que des pointeurs vers des objets.

L'opérateur == doit être utilisé pour comparer des valeurs primitives et pour comparer des références d'objet.

2

Réponse courte est non. En Java, il n'y a qu'une valeur de transmission, et lorsque vous travaillez avec des objets (par exemple Object obj = new Object();), vous travaillez avec des références d'objet. Lequel est passé en valeur.

Pour plus de détails, voir: Parameter passing in Java

4

Le point de distinction entre "passer ** - sous-référence" et "passer une référence ing **". Vous voyez aussi parfois "call-by -..." et "pass-by -..." utilisés de manière interchangeable. Pour la simplicité, je vais rester avec "pass-by -...".

  1. dans les milieux universitaires, de la vieille école, FORTRAN pertinentes, la terminologie comp-sci, passe par référence signifie que le code appelé a accès (référence) à une variable adoptée par l'appelant. L'affectation au paramètre formel dans le code appelé effectue réellement une affectation à la variable de l'appelant. La distinction est par rapport à (entre autres) valeur de passage, qui donne au code appelé une copie des données (quel qu'il soit) connues de l'appelant. Dans le monde contemporain orienté Java, «avoir une référence» à un objet signifie pouvoir accéder à l'objet lui-même. Cela se distingue de "avoir un pointeur" pour souligner (entre autres) que l'on ne fait pas de "pointeur arithmétique" sur une référence. (En fait, une « référence » dans ce sens ne doit pas nécessairement être une adresse mémoire de pointeur comme réelle.)

Java transmet des arguments par valeur (dans le premier sens), mais pour les arguments de l'objet, la valeur est une référence (au second sens). Voici un peu de code qui repose sur la différence.

// called 
public void munge(List<String> a0, List<String> a1) { 
    List<String> foo = new List<String>(); foo.add("everybody"); 
    a0.set(0, "Goodbye"); 
    a1 = foo; 
} 

// caller 
... 
List<String> l0 = new List<String>(); l0.add("Hello"); 
List<String> l1 = new List<String>(); l1.add("world"); 
munge(l0, l1); 
... 

Au retour de munge, la première liste de l'appelant, l0 contiendra "Goodbye". Une référence à cette liste a été transmise à munge, qui appelait une méthode de mutation sur cet objet référencé.(En d'autres termes, a0 a reçu une copie de la valeur de l0, qui était une référence à une liste de chaînes qui se est modifiée.)

Cependant, lors du retour de munge, deuxième liste de l'appelant, l1 encore contient "world" car aucune méthode n'a été appelée sur la référence d'objet transmise (la valeur de l1, transmise par la valeur à munge). Au lieu de cela, la variable d'argument a1 a été définie sur une nouvelle valeur (la référence d'objet local également détenue dans foo).

IF Java avait utilisé un passage par référence, lors du retour, l1 aurait contenu "everybody" parce a1 aurait appelé à la variable l1 et non simplement été initialisé à une copie de sa valeur. Donc, l'affectation à a1 aurait également été une affectation à l1.

Ce même problème a été discuté dans another question, avec ASCII-art pour illustrer la situation.

Questions connexes