Comparez les prix des domaines et des services informatiques des vendeurs du monde entier

Comment transmettre la classe Entier sur le lien?

J'espère que quelqu'un peut clarifier pour moi ce qui se passe ici. J'ai frappé un peu en classe integer, Mais depuis integer

Survoler

opérateur
+

, Je ne pouvais pas comprendre ce qui n'allait pas. Mon problème avec cette chaîne est:


Integer i = 0;
i = i + 1; // ← I think that this is somehow creating a new object!


Voici mon raisonnement:
Je sais que Java est pass by value /
https://coderoad.ru/40480/
/, Par conséquent, je pense que dans l'exemple suivant, un objet entier devrait augmenter à chaque fois.


public class PassByReference {

public static Integer inc/Integer i/ {
i = i+1; // I think that this must be **sneakally** creating a new integer...
System.out.println/"Inc: "+i/;
return i;
}

public static void main/String[] args/ {
Integer integer = new Integer/0/;
for /int i =0; i<10; i++/{
inc/integer/;
System.out.println/"main: "+integer/;
}
}
}


C'est mon résultat attendu:

Inc: 1
main: 1
Inc: 2
main: 2
Inc: 3
main: 3
Inc: 4
main: 4
Inc: 5
main: 5
Inc: 6
main: 6
...
C'est la production réelle.

Inc: 1
main: 0
Inc: 1
main: 0
Inc: 1
main: 0
...
Pourquoi se comporte-t-il comme ça?
Invité:

Hannah12

Confirmation de:

Il y a deux problèmes:

Un entier est transmis par la valeur, pas par référence. Changer la référence à l'intérieur de la méthode ne sera pas reflétée dans la liaison transmise de la méthode d'appel.

Un entier est immuable. Il n'y a pas de tel méthode que
Integer#set/i/

. Sinon, vous pourriez simplement l'utiliser.

Pour le forcer à travailler, vous devez réaffecter la méthode de retour de la méthode.
inc//

.


integer = inc/integer/;


Pour en apprendre un peu plus sur la transmission par valeur, voici un autre exemple:


public static void main/String... args/ {
String[] strings = new String[] { "foo", "bar" };
changeReference/strings/;
System.out.println/Arrays.toString/strings//; // still [foo, bar]
changeValue/strings/;
System.out.println/Arrays.toString/strings//; // [foo, foo]
}
public static void changeReference/String[] strings/ {
strings = new String[] { "foo", "foo" };
}
public static void changeValue/String[] strings/ {
strings[1] = "foo";
}

Gaspard

Confirmation de:

Un entier est immuable. Vous pouvez envelopper int Dans votre coquille de classe d'utilisateur.


class WrapInt{
int value;
}

WrapInt theInt = new WrapInt//;

inc/theInt/;
System.out.println/"main: "+theInt.value/;

Gilbert

Confirmation de:

Bonnes réponses ci-dessus expliquant la question réelle de OP.

Si une personne doit transmettre le nombre qui devrait être mis à jour globalement, utilisez
AtomicInteger/

/ Au lieu de créer différentes classes de shell proposées ou s'appuyant sur des bibliothèques tiers.


AtomicInteger/

/, Bien sûr, principalement utilisé pour l'accès à fil-sûr, mais si la chute des performances n'est pas un problème, pourquoi ne pas utiliser cette classe intégrée. Un bonus supplémentaire est bien sûr une sécurité de fil évidente.


import java.util.concurrent.atomic.AtomicInteger

Gilles

Confirmation de:

il y a 2 façon d'aller sous le lien

Utilisation
https://commons.apache.org/pro ... .html
de la bibliothèque Apache Commons.

Créez une classe d'utilisateurs comme indiqué ci-dessous

Voici un exemple de code pour cela:


public class Test {
public static void main/String args[]/ {
Integer a = new Integer/1/;
Integer b = a;
Test.modify/a/;
System.out.println/a/;
System.out.println/b/;

IntegerObj ao = new IntegerObj/1/;
IntegerObj bo = ao;
Test.modify/ao/;
System.out.println/ao.value/;
System.out.println/bo.value/;
}


static void modify/Integer x/ {
x=7;
}
static void modify/IntegerObj x/ {
x.value=7;
}
}

class IntegerObj {
int value;
IntegerObj/int val/ {
this.value = val;
}
}


Sortir:


1
1
7
7

Edouard

Confirmation de:

Ce que tu vois ici - Ce n'est pas un oparator surchargé
+

, Et comportement de bus. Classer
Integer

est immuable et votre code:


Integer i = 0;
i = i + 1;


Considéré par un compilateur /Après un bus/ comme:


Integer i = Integer.valueOf/0/;
i = Integer.valueOf/i.intValue// + 1/;


Donc, vous avez raison dans votre conclusion qu'une instance
Integer

changé, mais pas caché - Ceci est cohérent avec la définition de la langue Java :-/

Agathe

Confirmation de:

Ici vous avez raison:


Integer i = 0;
i = i + 1; // <- I think that this is somehow creating a new object!


Premièrement: un entier est immuable.

Deuxièmement: la classe d'entier ne remplace pas l'opérateur
+

, Dans cette ligne, il y a une boîte automatique et aide /dans les anciennes versions Java Vous obtiendrez une erreur dans la ligne ci-dessus/.

Quand vous écrivez
i + 1

, Le compilateur d'abord convertit un entier dans /primitif/
int

Pour effectuer une addition: autounboxing. Suivant, faisant
i = <some int="">

Le compilateur convertit la valeur
int

à /Nouveau/ entier: autoboxing.

De cette façon,
+

effectivement appliqué à la primitive
int

s.
</some>

Guillaume

Confirmation de:

Je pense que c'est un bus qui vous confond.

Cette partie de votre code:


public static Integer inc/Integer i/ {
i = i+1; // I think that this must be **sneakally** creating a new integer...
System.out.println/"Inc: "+i/;
return i;
}


Cela revient vraiment au code qui ressemble à ceci:


public static Integer inc/Integer i/ {
i = new Integer/i/ + new Integer/1/;
System.out.println/"Inc: "+i/;
return i;
}


Ce qui va sans dire .. ne change pas les liens transmis.

Vous pouvez le corriger avec quelque chose comme ça


public static void main/String[] args/ {
Integer integer = new Integer/0/;
for /int i =0; i<10; i++/{
integer = inc/integer/;
System.out.println/"main: "+integer/;
}
}

Hannah

Confirmation de:

Si vous changez de fonction inc// Sur ce


public static Integer inc/Integer i/ {
Integer iParam = i;
i = i+1; // I think that this must be **sneakally** creating a new integer...
System.out.println/i == iParam/;
return i;
}


Alors vous verrez qu'il imprime toujours "false".
Cela signifie que l'ajout crée une nouvelle copie. Integer et l'enregistre dans

Local

variable i /"local", car i est en fait une copie du lien référencé/, Laissant la variable de la méthode causée intacte.

Entier est une classe immuable, c'est-à-dire que vous ne pouvez pas changer sa valeur, mais devriez avoir une nouvelle instance. Dans ce cas, vous n'avez pas à le faire manuellement comme ceci:


i = new Integer/i+1/; //actually, you would use Integer.valueOf/i.intValue//+1/;


Au lieu de cela, cela se fait avec l'aide de Supersay.

Darius

Confirmation de:

1 / En tant que valeur du paramètre formel, seule une copie de la référence est envoyée. Lorsque la variable du paramètre formel est attribuée une autre valeur, la référence du paramètre formel varie, mais la référence de paramètre réelle reste la même dans le cas de cet objet entier.

Classe ouverte UnderstandingObjects {


public static void main/String[] args/ {

Integer actualParam = new Integer/10/;

changeValue/actualParam/;

System.out.println/"Output " + actualParam/; // o/p =10

IntObj obj = new IntObj//;

obj.setVal/20/;

changeValue/obj/;

System.out.println/obj.a/; // o/p =200

}

private static void changeValue/Integer formalParam/ {

formalParam = 100;

// Only the copy of reference is set to the formal parameter
// this is something like => Integer formalParam =new Integer/100/;
// Here we are changing the reference of formalParam itself not just the
// reference value

}

private static void changeValue/IntObj obj/ {
obj.setVal/200/;

/*
* obj = new IntObj//; obj.setVal/200/;
*/
// Here we are not changing the reference of obj. we are just changing the
// reference obj's value

// we are not doing obj = new IntObj// ; obj.setValue/200/; which has happend
// with the Integer

}


}

Classer IntObj {
Entier a;


public void setVal/int a/ {
this.a = a;
}


}

Pour répondre aux questions, connectez-vous ou registre