2013-01-14 1 views
0

Possible en double:
Is Java “pass-by-reference”?JAVA passe par valeur Vs passe par référence

Je suis en train de comprendre la différence entre les 2 programmes JAVA écrit ci-dessous:

public class Swapping { 

public static void main(String[] args) { 

    IntWrap i = new IntWrap(10); 
    IntWrap j = new IntWrap(20); 

    swap(i, j); 
    System.out.println("i " + i.i + ", j " + j.i); 
} 

public static void swap(IntWrap i , IntWrap j){ 

    int x = i.i; 
    i.i = j.i; 
    j.i = x; 

    System.out.println("i " + i.i + ", j " + j.i); 
} 

} 

public class IntWrap { 

int i; 
public IntWrap(int i){ 
    this.i = i; 
} 

} 

Sortie:

i 20, j 10 
i 20, j 10 

et 2ème: -

Permutation public class {

public static void main(String[] args) { 

    Integer i = new Integer(10); 
    Integer j = new Integer(20); 

    swap(i, j); 
    System.out.println("i " + i + ", j " + j); 
} 

public static void swap(Integer i , Integer j){ 

    Integer temp = new Integer(i); 
    i = j; 
    j = temp; 

    System.out.println("i " + i + ", j " + j); 
} 

} 

Sortie:

i 20, j 10 
i 10, j 20 

Je ne suis pas en mesure de comprendre que je même si je passe Integer objet, il devrait être permuté dans le programme d'origine. Quelle différence cela a-t-il créé si j'ai écrit la classe wrapper sur le dessus alors que je ne fais que passer à nouveau l'objet ... Veuillez répondre avec des explications détaillées seulement, si vous en avez.

+0

[Il n'y a pas de cuillère] (http://www.urbandictionary.com/define.php?term=there%20is%20no%20spoon) –

+0

'entier I' n'est pas un objet. C'est une * référence * à un objet. Vous passez une référence par valeur. –

Répondre

1

Java utilise l'appel par valeur à transmettre tout ce que vous arguments.When passer l'objet à une fonction, la référence d'objet (adresse de l'objet) est passé en valeur. Dans le second programme, vous attribuez i = j et j = temp. Donc i = adresse de 20 j = adresse de 10 (nouvel objet) Mais après le retour de l'échange, dans le programme principal, je pointe toujours vers 10 et j pointe vers 20.C'est pourquoi vous obtenez 10 et 20 retour dans le programme principal.

Mais dans le premier programme, vous passez l'adresse de vos objets à la fonction swap et dans la fonction swap vous modifiez le contenu de l'objet pointé par ces adresses.C'est pourquoi, il est réfléchi dans la méthode principale.

+0

Merci ... C'est la meilleure explication :) – ASingh

1

Ups. Integer Les objets sont immuables en Java. Vous ne pouvez pas changer leurs valeurs internes ni d'une autre méthode, ni du tout. Créez uniquement un nouvel objet Integer.

+0

Ce n'est pas exactement le problème - dans un cas il modifie un champ d'un objet alors que dans l'autre cas il réattribue un objet. Cela aurait le même effet avec un objet mutable. – assylias

+1

@assylias Peut-être avons-nous un malentendu sur ma réponse. Dans le premier cas, il change simplement les valeurs des champs de l'objet IntWrap. C'est bon. Dans la seconde, il essaie de changer les références de l'objet 'Integer'. Il ne pouvait pas travailler avec des objets 'Integer' d'une autre façon en raison de leur nature immuable (il n'y a pas de' setValue' pour eux et bla-bla). Mais une description explicite de pourquoi il ne pouvait pas changer de référence à partir d'une autre méthode est vraiment nécessaire, je suis d'accord. – Andremoniy

4

Tous les paramètres de méthode, y compris les références d'objet, sont transmis par valeur en Java. Vous pouvez assigner n'importe quelle valeur au paramètre de méthode - la valeur originale dans le code appelant ne sera pas modifiée. Cependant, vous pouvez modifier l'objet transmis lui-même et les modifications persisteront lorsque la méthode reviendra.

Il existe d'anciennes classes Holder dans l'API J2SE, spécialement conçues pour prendre en charge les appels à des méthodes avec des "paramètres renvoyables" (IntHolder ou StringHolder, par exemple). Ils sont principalement utilisés avec le code généré à partir du langage IDL, car IDL nécessite la prise en charge des paramètres in, out et inout. Ces supports sont très rares dans d'autres codes.

Vous pouvez également simuler le passage par référence en utilisant des tableaux:

String [] a = new String[1]; String [] b = new String[1]; 

void swap(String [] a, String [] b) { 
    String t = a[0]; a[0] = b[0]; b[0] = t; 
} 
+0

Il peut également jeter un oeil à http://javadude.com/articles/passbyvalue.htm, c'est très bien expliqué – SomeJavaGuy

0

(Si vous ne connaissez pas les pointeurs et les références que je vous conseille d'aller sur eux un peu, le monde aura plus de sens - Intro to Pointers)

Mettre vers le bas à la plus explication la plus simple, il y a 2 façons java tout passaient et repassaient:

  • Pass-by = Valeur: Utilisé pour les objets immuables (String, Integer, Double, etc.). Ces valeurs ne peuvent pas changer à une exception si vous recréez l'objet.

    String x = "World"; <- String x = new String("World"); 
        x = "Hello"; <- x = new String("Hello"); 
        x = x + " World"; <- x = new String("Hello" + " World"); 
        printOutString(x); <- printOutString("Hello World"); 
    

tenue à une position de mémoire. Toute modification crée un nouvel objet sans relation avec le précédent et regarde un emplacement de mémoire séparé.

  • passe par référence: pour les objets non immuables (classes, int, double, etc.). Ces valeurs peuvent être modifiées et conserver leur ancienne place en mémoire.

    int i = 1; 
        i = 2; <- value at <reference-to-memory-as-value> = 2; 
        i = i + 1; <- value at <reference-to-memory-as-value> + 1; 
        printOutInteger(i); <- printOutInteger(value at <reference-to-memory-as-value>); 
    

Toute modification de cet objet est fait à l'emplacement de la mémoire. Par conséquent, l'emplacement ne change jamais (sauf si vous créez un nouvel objet).

La même chose se produit dans vos programmes. Les objets qui disent une chose dans la méthode, puis reviennent aux valeurs précédentes. Vous êtes, en quelque sorte, Operator Overloading. Vous affectez de nouvelles valeurs aux objections (Integer dans ce cas) que vous envoyez, MAIS vous avez passé les valeurs qui signifie Integer i dans la méthode, parce que Integer est immuable, regarde un emplacement de mémoire différent au Integer i dans le méthode principale. Par conséquent, lorsque la méthode se termine, les objets que vous avez transmis sont éliminés et Integer i et j regardent maintenant leurs emplacements de mémoire d'origine.

Lorsque vous avez passé les classes avec les objets int, car ils sont passés ont été pas les emplacements de mémoire immuables (en valeur) et les valeurs à ces endroits ont été travaillé. C'est pourquoi les changements ici ont été montrés dans les objets originaux.

J'espère que cette aide