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

Duplication possible:
Java est-il une référence par référence?

Les tableaux ne sont pas un type primitif en Java, mais ce ne sont pas non plus des objects , 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?

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

Les tableaux ne sont pas un type primitif en Java, mais ce ne sont pas non plus des objects … “

En fait, tous les tableaux de Java sont des objects 1 . Chaque type de tableau Java a comme supertype java.lang.Object et hérite de l’implémentation de toutes les méthodes de l’API Object .

Comme tous les objects Java, les tableaux sont passés par valeur … mais la valeur est la référence au tableau.

Le passage réel par référence consiste à passer l’adresse d’une variable afin que la variable puisse être mise à jour. Ce n’est pas ce qui se passe lorsque vous passez un tableau en Java.

Voici quelques liens expliquant la différence entre “pass-by-reference” et “pass-by-value”:

Question SO connexe:

  • Est-ce que Java “pass-by-reference” ou “pass-by-value”?

Contexte historique:

L’expression “pass-by-reference” était à l’origine “call-by-reference”, et elle était utilisée pour distinguer l’argument passant la sémantique de FORTRAN (call-by-reference) de ceux de ALGOL-60 (call-by-value). et appel par nom).

  • Dans call-by-value, l’expression de l’argument est évaluée à une valeur et cette valeur est copiée dans la méthode appelée.

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

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

METTRE À JOUR

En fait, l’appel par nom d’Algol-60 est similaire au passage d’expressions lambda en tant que parameters. La ride est que ces expressions pas exactement lambda (appelées “thunks” au niveau de l’implémentation) peuvent modifier indirectement l’état des variables qui sont dans la scope de la procédure / fonction appelante. Cela fait partie de ce qui les rend si difficiles à comprendre. (Voir la page Wikipedia sur le périphérique de Jensen, par exemple.)


1. Rien dans les Q & A liés ( tableaux dans Java et comment ils sont stockés en mémoire ) n’indique ou implique que les tableaux ne sont pas des objects.

Everything in Java are passed-by value. . Dans le cas d’un tableau (qui n’est autre qu’un object), la référence de tableau est passée par valeur. (Tout comme une référence d’object est passée par valeur).

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

  • Toute modification du contenu du tableau par cette référence affectera le tableau d’origine.
  • Mais changer la référence à pointer sur un nouveau tableau ne changera pas la référence existante dans la méthode d’origine.

Voir ce post ..

Est-ce que Java “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(Ssortingng[] 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.. } 

Les tableaux sont en fait des objects, donc une référence est passée (la référence elle-même est passée par valeur, encore confuse?). Exemple rapide:

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

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

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

Si vous transmettez une liste non nulle, elle ne sera pas nulle au moment où la méthode sera retournée.

Non c’est faux. Les tableaux sont des objects spéciaux en Java. Donc, c’est comme passer d’autres objects où vous passez la valeur de la référence, mais pas la référence elle-même. Cela signifie que la modification de la référence d’un tableau dans la routine appelée ne sera pas reflétée dans la routine d’appel.

Tout en Java est passé par valeur.

Dans le cas du tableau, la référence est copiée dans une nouvelle référence, mais rappelez-vous que tout en Java est transmis par valeur.

Jetez un oeil à cet article intéressant pour plus d’informations …

La discussion définitive sur les tableaux se trouve à l’ adresse http://docs.oracle.com/javase/specs/jls/se5.0/html/arrays.html#27803 . Cela montre clairement que les tableaux Java sont des objects. La classe de ces objects est définie au 10.8.

La section 8.4.1 de la spécification de langue, http://docs.oracle.com/javase/specs/jls/se5.0/html/classes.html#40420 , décrit comment les arguments sont transmis aux méthodes. Comme la syntaxe Java est dérivée de C et C ++, le comportement est similaire. Les types primitifs sont passés par valeur, comme avec C. Lorsqu’un object est transmis, une référence d’object (pointeur) est transmise par valeur, reflétant la syntaxe C consistant à transmettre un pointeur par valeur. Voir 4.3.1, http://docs.oracle.com/javase/specs/jls/se5.0/html/typesValues.html#4.3 ,

En termes pratiques, cela signifie que la modification du contenu d’un tableau dans une méthode est reflétée dans l’object tableau dans la scope d’appel, mais la réaffectation d’une nouvelle valeur à la référence dans la méthode n’a aucun effet sur la référence dans la scope d’appel. est exactement le comportement que vous attendriez d’un pointeur sur une structure en C ou d’un object en C ++.

Au moins une partie de la confusion dans la terminologie provient de l’histoire des langages de haut niveau avant l’utilisation courante de C. Dans les langages antérieurs populaires et de haut niveau, il fallait éviter autant que possible de référencer directement la mémoire par adresse. a été considéré comme le travail du langage pour fournir une couche d’abstraction. Il était donc nécessaire que le langage prenne explicitement en charge un mécanisme de retour des valeurs des sous-programmes (pas nécessairement des fonctions). Ce mécanisme est ce que l’on entend par «faire référence».

Lorsque C a été introduit, il est venu avec une notion simplifiée d’appel de procédure, où tous les arguments sont en entrée uniquement, et la seule valeur renvoyée à l’appelant est un résultat de fonction. Cependant, l’object des références pourrait être atteint grâce à l’utilisation explicite et large de pointeurs. Comme il sert le même but, la pratique consistant à faire passer un pointeur comme référence à une valeur est souvent appelée familièrement par un passage par référence. Si la sémantique d’une routine appelle un paramètre à passer par référence, la syntaxe de C nécessite que le programmeur passe explicitement un pointeur. Passer un pointeur par valeur est le modèle de conception pour implémenter la sémantique de référence par référence dans C.

Comme il semble souvent que le seul but des pointeurs bruts dans C est de créer des bogues, les développements ultérieurs, en particulier Java, ont cherché à retrouver des moyens plus sûrs pour transmettre les parameters. Cependant, la domination de C obligeait les développeurs à imiter le style familier du codage en C. Le résultat est que les références sont passées de la même manière que les pointeurs, mais sont implémentées avec plus de protections pour les rendre plus sûres. Une alternative aurait été la riche syntaxe d’un langage comme Ada, mais cela aurait présenté l’apparence d’une courbe d’apprentissage indésirable et réduit l’adoption probable de Java.

En bref, la conception de la transmission de parameters pour les objects, y compris les tableaux, en Java, sert essentiellement à servir l’intention sémantique du passage par référence, mais elle est nestede avec la syntaxe de passage d’une référence par valeur.

Sorte de truc de realty … Même les références sont passées par valeur en Java, d’où un changement de la référence elle-même au niveau de la fonction appelée. Le compilateur et / ou JVM transformeront souvent un type de valeur en référence.