Quand j’écris comme ceci:
public class test { void mainx() { int fyeah[] = {2, 3, 4}; smth(fyeah); System.out.println("x"+fyeah[0]); } void smth(int[] fyeah) { fyeah[0] = 22; } }
Il imprime x22;
Quand j’écris comme ceci:
public class test { void mainx() { int fyeah = 5; smth(fyeah); System.out.println("x"+fyeah); } void smth(int fyeah) { fyeah = 22; } }
Il n’imprime pas x22, mais imprime x5.
Pourquoi, dans la deuxième version, la valeur ne change-t-elle pas? Cela change-t-il les valeurs uniquement pour les éléments de tableau?
La variable fyeah
dans votre premier exemple contient une référence à un tableau (pas un tableau), tandis que l’entier fyeah
dans votre deuxième exemple contient un entier .
Puisque Java passe tout par valeur, voici ce qui se passera:
Dans le cas d’un tableau: une copie de la référence du tableau sera envoyée et le tableau d’origine sera modifié.
Dans le cas int: Une copie de l’entier sera modifiée et l’entier d’origine ne sera pas modifié.
C’est parce que votre int est une primitive et que la méthode smth
crée une copie locale, c’est pourquoi elle n’imprime pas comme vous le souhaitez. Les objects sont également transmis par valeur, mais une valeur pour le pointeur en mémoire. Ainsi, quand il est modifié, le pointeur rest dans les deux méthodes et vous voyez le changement. Lire plus ici
D’accord. Un int en java (et toutes les langues ayant un typage de données ssortingct) est un type de données primitif. C’est juste une seule variable de ce type de données. En java, cela signifie qu’il est passé par valeur à la méthode. Ainsi, lorsque vous transmettez l’argument, une copie de la variable transmise est créée. Toutes les opérations qui ont lieu dans la méthode agissent sur cette copie et non sur la variable transmise.
En réalité, tout est passé en java par valeur, mais entrer dans les détails de la manière dont cela est vrai avec ce que je vais dire semble tout à fait déconseillé.
Avec le tableau … il s’agit d’une collection de variables du type de données primitif int. Ainsi, une copie complète du tableau n’est pas en réalité une copie de la référence à la mémoire qui stocke le tableau. alors oui, la valeur de la valeur IN du tableau est modifiée à partir des opérations de la méthode.
En bref, les méthodes ne changent pas la valeur externe des primitives (int, float, double, long, char) avec les opérations de la méthode, vous devez renvoyer la valeur résultante de ces opérations à l’appelant si vous souhaitez l’obtenir. Les opérations changent la valeur avec la plupart des objects ainsi qu’avec les tableaux de primitives. J’espère que cela pourra aider. Vraiment pas sûr du niveau bas à obtenir. Peut-être que quelqu’un d’autre peut expliquer clairement pourquoi c’est par sa valeur. Je «comprends», mais j’ai du mal à aider les autres à comprendre.
Le int
est un type de valeur, donc 5 est passé directement à smth
qui ne peut modifier que la copie locale. En revanche, un tableau est un type de référence afin que les éléments de ce tableau puissent être modifiés.
En le voyant un peu moins techniquement, je dirais que
fyeah[0] = 22;
change le contenu de (l’object pointé par) fyeah, tandis que
fyeah = 22;
est en train de changer (la variable) fyeah elle-même.
Un autre exemple:
void smth(Person person) { person.setAge(22); }
change (le contenu de) la personne en
void smth(Person person) { person = otherPerson; }
change la variable person – l’instance d’origine de Person rest inchangée (et, étant donné que Java est une valeur transmise par valeur, la variable du code appelant n’est pas modifiée par cette méthode)
Pensez-y en termes de mémoire: analysons votre premier programme –
Dans mainx
, fyeah
est un tableau d’ mainx
, fyeah
donc une référence (ou un pointeur si je peux). Cette référence pointe vers un emplacement dans la mémoire de tas où le tableau réel d’ int
est stocké. Disons à l’adresse 100. Il y a trois ints contigus (disons à l’adresse 100, 104 et 108, respectivement, 2, 3 et 4).
Vous appelez maintenant votre méthode smth
et passez la référence. Dans la méthode, il existe une autre référence (de type tableau int
) appelée fyeah
. Ce fyeah
est assez différent de fyeah
reference dans la méthode mainx
. Maintenant, lorsque vous appelez smth
et passez le fyeah
de mainx
, le fyeah
de la méthode est initialisé pour pointer vers le même emplacement (c’est-à-dire l’adresse mémoire 100). Lorsque vous accédez à l’élément 0 de fyeah
et lui atsortingbuez la valeur 22, il atteint l’emplacement de mémoire de 100 et écrit cette valeur 22 à cet endroit. Lorsque vous revenez dans votre méthode mainx
, la référence à fyeah
fait toujours référence à l’adresse de mémoire 100. Mais la valeur présente à cet emplacement est maintenant 22. Vous obtenez donc cette valeur lorsque vous accédez au premier élément de fyeah
dans mainx
.
Maintenant, votre deuxième programme. Votre méthode mainx
déclare un int
(pas un tableau, mais un simple int
) et le définit sur 5. Cette variable fyeah
est créée sur une stack et non sur le tas. La valeur de 5 est stockée sur la stack. Maintenant, vous appelez smth
et transmettez cette variable. Dans la méthode smth
, vous déclarez à nouveau une variable int
, fyeah
par nom (en tant qu’argument de méthode formelle). Encore une fois, ceci est distinct du fyeah
de la méthode mainx
et ce fyeah
est également créé sur une fyeah
Cette variable sera initialisée à une valeur de 5, recopiée du fyeah
vous avez passé comme argument. Notez maintenant qu’il existe deux copies distinctes sur les variables fyeah
, les deux sur la stack et la valeur 5. Maintenant, vous affectez à fyeah
une valeur de 22. Cela n’affectera pas le fyeah
de la méthode mainx
, donc lorsque vous revenez à mainx
et access fyeah
, vous voyez 5.