235 votes

Les tableaux sont-ils transmis par valeur ou par référence en Java ?

Les tableaux ne sont pas une type primitif en Java, mais ils ne sont pas non plus des objets Les données sont-elles transmises par valeur ou par référence ? Cela dépend-il de ce que contient le tableau, par exemple des références ou un type primitif ?

304voto

Rohit Jain Points 90368

En Java, tout est transmis par valeur. Dans le cas d'un tableau (qui n'est rien d'autre qu'un objet), la référence du tableau est passée par valeur (tout comme une référence d'objet est passée par valeur).

Lorsque vous passez un tableau à une autre méthode, la référence à ce tableau est en fait copiée.

  • Toute modification du contenu du tableau à travers cette référence affectera le tableau original.
  • Mais changer la référence pour pointer vers un nouveau tableau ne changera pas la référence existante dans la méthode originale.

Voir ce billet : Java est-il "pass-by-reference" ou "pass-by-value" ?

Voir cet exemple de travail :

public static void changeContent(int[] arr) {

   // If we change the content of arr.
   arr[0] = 10;  // Will change the content of array in main()
}

public static void changeRef(int[] arr) {
   // If we change the reference
   arr = new int[2];  // Will not change the array in main()
   arr[0] = 15;
}

public static void main(String[] args) {
    int [] arr = new int[2];
    arr[0] = 4;
    arr[1] = 5;

    changeContent(arr);

    System.out.println(arr[0]);  // Will print 10.. 

    changeRef(arr);

    System.out.println(arr[0]);  // Will still print 10.. 
                                 // Change the reference doesn't reflect change here..
}

172voto

Stephen C Points 255558

Votre question est basée sur une fausse prémisse.

Les tableaux ne sont pas un type primitif en Java, mais ils ne sont pas non plus des objets ... "

En fait, tous les tableaux en Java sont objets 1 . Chaque type de tableau Java possède java.lang.Object comme son supertype, et hérite de l'implémentation de toutes les méthodes de la classe Object API.

... alors sont-ils transmis par valeur ou par référence ? Cela dépend-il de ce que contient le tableau, par exemple des références ou un type primitif ?

Réponses courtes : 1) passe par la valeur, et 2) cela ne fait aucune différence.

Réponse plus longue :

Comme tous les objets Java, les tableaux sont transmis par valeur... mais la valeur est la référence au tableau. Ainsi, lorsque vous affectez quelque chose à une cellule du tableau dans la méthode appelée, vous l'affectez au même objet tableau que l'appelant voit.

Il ne s'agit PAS d'une transmission par référence. Real pass-by-reference implique de passer le adresse d'une variable . Avec real pass-by-reference, la méthode appelée peut assigner à sa variable locale, et cela provoque la mise à jour de la variable dans l'appelant.

Mais pas en Java. En Java, la méthode appelée peut mettre à jour le contenu du tableau, et elle peut mettre à jour sa copie de la référence au tableau, mais elle ne peut pas mettre à jour la variable de l'appelant qui contient la référence au tableau de l'appelant. Par conséquent... ce que Java fournit n'est PAS le pass-by-reference.

Voici quelques liens qui expliquent la différence entre pass-by-reference et pass-by-value. Si vous ne comprenez pas mes explications ci-dessus, ou si vous êtes en désaccord avec la terminologie, vous pouvez devrait les lire.

Question connexe sur le SO :

Contexte historique :

L'expression "pass-by-reference" était à l'origine "call-by-reference", et elle était utilisée pour distinguer la sémantique du passage d'argument de FORTRAN (call-by-reference) de celle d'ALGOL-60 (call-by-value et call-by-name).

  • Dans le cas du call-by-value, l'expression de l'argument est évaluée en une valeur, et cette valeur est copiée dans la méthode appelée.

  • Dans l'appel par référence, l'expression de l'argument est partiellement évaluée en une "lvalue" (c'est-à-dire l'adresse d'une variable ou d'un élément de tableau) qui est transmise à la méthode appelante. La méthode appelante peut alors lire et mettre à jour directement la variable ou l'élément.

  • Dans le cas du call-by-name, l'expression réelle de l'argument est transmise à la méthode appelante ( !!) qui peut l'évaluer plusieurs fois ( !!!). Ceci était compliqué à mettre en oeuvre, et pouvait être utilisé (abusivement) pour écrire du code très difficile à comprendre. Le call-by-name n'a jamais été utilisé que dans Algol-60 (heureusement !).

UPDATE

En fait, l'appel par nom d'Algol-60 est similaire au passage d'expressions lambda comme paramètres. Le problème est que ces expressions lambda qui ne sont pas exactement des expressions lambda (elles sont appelées "thunks" au niveau de l'implémentation) peuvent être utilisées comme paramètres. indirectement modifier l'état des variables qui sont dans la portée de la procédure/fonction appelante. C'est en partie ce qui les rend si difficiles à comprendre. (Voir la page Wikipedia sur Dispositif de Jensen par exemple).


1. Rien dans les questions et réponses liées ( Les tableaux en Java et la manière dont ils sont stockés en mémoire ) affirme ou implique que les tableaux ne sont pas des objets.

65voto

Tudor Points 39539

Les tableaux sont en fait des objets, donc une référence est transmise (la référence elle-même est transmise par valeur, vous ne comprenez pas encore ?) Exemple rapide :

// assuming you allocated the list
public void addItem(Integer[] list, int item) {
    list[1] = item;
}

Vous verrez les modifications apportées à la liste à partir du code d'appel. Cependant, vous ne pouvez pas modifier la référence elle-même, puisqu'elle est passée par valeur :

// assuming you allocated the list
public void changeArray(Integer[] list) {
    list = null;
}

Si vous passez une liste non nulle, elle ne sera pas nulle au moment du retour de la méthode.

13voto

sakthisundar Points 1628

Non, c'est faux. Les tableaux sont des objets spéciaux en Java. Donc c'est comme passer d'autres objets où vous passez la valeur de la référence, mais pas la référence elle-même. Autrement dit, changer la référence d'un tableau dans la routine appelée ne sera pas reflété dans la routine appelante.

4voto

aleroot Points 30853

Tout en Java est transmis par valeur .

Dans le cas du tableau, la référence est copiée dans une nouvelle référence, mais n'oubliez pas que tout en Java est transmis par valeur .

Jetez un coup d'œil à cet article intéressant pour plus d'informations ...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X