2009-01-28 11 views
11

J'ai une question sur la modification des valeurs des variables dans les méthodes en Java.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 ne change pas - il reste à 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 les changements de tableau, parce que nous avons la déclaration b[0] = b[0] * 2;

I ne comprends pas pourquoi une chose change et l'autre non? Quelqu'un pourrait-il expliquer cela pour moi?

Répondre

17

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

En bref (regarder son site pour une plus toute explication):

Les tableaux sont les types de référence. Si vous transmettez une référence pointant 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 pointe donc vers le même tableau que l'argument passé. Ainsi, les modifications que vous apportez au tableau via le paramètre de votre fonction seront visibles dans la fonction d'appel. Changer le paramètre lui-même (b), par exemple en le réglant sur null, ne sera cependant pas remarqué par la fonction appel, puisque le paramètre (b) n'est qu'une copie de l'argument (tiger) passé.

Les entiers sont des types dits primitifs. Passer l'entier copie sa valeur et l'affecte 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 d'appel (oiseau).

4

C'est parce que quand vous déclarez

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

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

À propos du b. Voilà une nouvelle référence d'objet au même tableau créé dans le principal, c'est pourquoi il semble la valeur ne change (ce qui change est l'objet du tableau ci-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 que vous la valeur du tigre ne change pas non plus (seulement le contenu du nouveau tableau c créé dans funk)

Vous pouvez simuler le passage par ref en utilisant un wrapper.See this post.

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

EDIT Juste pour le plaisir:

J'ai modifié votre code pour utiliser l'emballage affiché ci-dessus.

Il semble assez étrange, mais ressemble à cela fonctionne.

// 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]); 

    } 

} 

Prints

bird = 19 
tiger = 14 

: -S

4

Fondamentalement, les objets (comme les tableaux) sont passés dans des procédés "par référence". Ainsi, lorsque vous changez l'objet, il change le même objet qui a été transmis à la méthode.

Primitives (comme int) sont « passés par valeur », de sorte que la variable que vous attribuez une valeur à un n'est pas la même chose que la variable int qui a été passé.

J'espère que cela aide .. .

+1

non, il ne vous aide pas. Java est TOUJOURS valeur de passage. Lisez les liens fournis dans les autres réponses; Vous devez comprendre cela. –

+0

Pour cet exemple, mon explication de base est correcte. J'ai précisé que c'était une explication de base. Si le questionneur veut lire une explication plus en profondeur, les liens sont là pour lui. Je n'ai aucun moyen de dire combien de détails il a besoin, alors pensé qu'il pourrait apprécier le choix. – stephendl

+1

Oui, je l'ai apprécié. J'ai également lu les liens, mais des explications plus courtes sont également utiles pour vous aider à démarrer. Merci à tous. – user42155

Questions connexes