web-dev-qa-db-fra.com

Changer les valeurs des variables dans les méthodes, Java

J'ai une question sur la modification des valeurs des variables dans les méthodes Java.

Ceci est mon code:

public class Test {
    public static void funk(int a, int[] b) { 
        b[0] = b[0] * 2; 
        a = b[0] + 5;
    } 

    public static void main(String[] args) {
        int bird = 10;
        int[] tiger = {7};

        Test.funk(bird, tiger);
    }
}

Après l'exécution de la méthode Test.funk(bird, tiger), la valeur de l'oiseau n'est pas modifiée - elle reste avec la valeur 10, même si, dans la méthode funk(), nous avons modifié la valeur avec a = b[0] + 5;.

D'autre part, la valeur de l'élément dans le tableau change, car nous avons l'instruction b[0] = b[0] * 2;

Je ne comprends pas pourquoi une chose change et l'autre pas? Quelqu'un pourrait-il s'il vous plaît expliquer cela pour moi.

13
user42155

Regardez l'article de Jon Skeet sur Parameter-Passing in Java , qui explique cela. 

En bref (regardez son site pour une explication plus complète): 

Les tableaux sont des types de référence. Si vous transmettez une référence qui pointe vers un tableau, la valeur de la référence est copiée et affectée au paramètre de la fonction. Le paramètre pointera donc sur le même tableau que l'argument qui a été passé. Ainsi, les modifications que vous apportez au tableau via le paramètre de votre fonction seront visibles dans la fonction appelante. Changer le paramètre lui-même (b), par exemple en le mettant sur null ne sera toutefois pas remarqué par la fonction appelante, car le paramètre (b) est simplement une copie de l'argument (tigre) transmis .

Les entiers sont des types dits primitifs. Le passage de l'entier copie sa valeur et l'assigne également au paramètre. Mais cette valeur n'est pas une référence aux données réelles, mais les données elles-mêmes. Ainsi, les modifications apportées au paramètre dans la fonction affecteront le paramètre (a), mais pas l'argument transmis dans la fonction appelante (oiseau). 

17

C'est parce que quand vous déclarez 

 public static void funk(int a, int[] b) 

La portée de la variable a n'est que cette méthode. Ensuite, lorsque vous modifiez la valeur, vous modifiez uniquement la valeur de that variable dans that méthode.

À propos de la b. C’est une nouvelle référence d’objet au même tableau créé dans main, c’est pourquoi il semble que la valeur change (ce qui est en train de changer est l’objet tableau en dessous)

Mais essayez ceci:

public static void funk(int a, int[] b) { 
    // create a new reference for b
    int[] c = new int[b.length];
    c[0] = b[0];
    b = c;

    // The same.
    b[0] = b[0] * 2; 
    a = b[0] + 5;
} 

Lorsque vous faites cela, la valeur de tiger ne change pas non plus (uniquement le contenu du nouveau tableau c créé dans funk) 

Vous pouvez simuler la passe par référence à l'aide d'un wrapper. Voir ce post.

Bien que je n'ai pas de commentaires à ce sujet

EDIT Juste pour le plaisir:

J'ai modifié votre code pour utiliser le wrapper affiché ci-dessus.

Cela semble assez étrange mais semble fonctionner.

// By ref simulated.
public class Test {

    public static void funk(_<Integer> a, int[] b) { 
        b[0] = b[0] * 2; 
        a.s(  b[0] + 5 ) ;
    } 

    public static void main(String[] args) {
        _<Integer> bird = new _<Integer>(10);
        int[] tiger = {7};

        Test.funk( bird , tiger );

        System.out.println("bird = " + bird );
        System.out.println("tiger = " + tiger[0] );

    }

}

Impressions

bird = 19
tiger = 14

: -S

4
OscarRyz

Fondamentalement, les objets (comme les tableaux) sont passés aux méthodes "par référence". Ainsi, lorsque vous modifiez l'objet, il modifie le même objet qui a été transmis à la méthode.

Les primitives (comme int) étant "passées par valeur", la variable à laquelle vous affectez une valeur dans a n'est pas identique à la variable int qui a été transmise.

J'espère que ça aide...

4
stephendl

Une variable passe par référence et l'autre par valeur :)

Quelle est la différence entre le passage par référence et le passage par valeur?

0
kjv.007