更改方法中的变量值,Java

时间:2009-01-28 23:40:33

标签: java scope

我有一个关于在Java中更改方法中变量值的问题。

这是我的代码:

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);
    }
}

执行方法Test.funk(bird, tiger)后,bird的值不会更改 - 它保留值10,即使在funk()方法中我们更改了值a = b[0] + 5;

另一方面,数组中元素的值会发生变化,因为我们有语句b[0] = b[0] * 2;

我不明白为什么一件事改变而另一件事没改变?有人可以帮我解释一下。

4 个答案:

答案 0 :(得分:18)

请看Jon Skeet关于Parameter-Passing in Java的文章,其中解释了这一点。

简而言之(请查看他的网站以获得更多解释):

数组是引用类型。如果传递指向数组的引用,则复制引用的值并将其分配给函数的参数。因此该参数将指向与传递的参数相同的数组。因此,通过函数参数对数组所做的更改将在调用函数中可见。然而,更改参数本身(b),例如通过将其设置为 null ,调用函数将不会注意到,因为参数(b)只是参数的副本(tiger)过去了。

整数是所谓的原始类型。传递整数会复制其值并将其分配给参数。但该值不是对实际数据的引用,而是数据本身。因此,对函数中参数的更改将影响参数(a),但不会影响调用函数(bird)中传递的参数。

答案 1 :(得分:4)

那是因为当你宣布

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

变量 a 的范围只是该方法。然后,当您更改值时,您只更改 方法中那个变量的值。

关于b。这是对在main中创建的同一个数组的新对象引用,这就是为什么它似乎值确实发生了变化(正在改变的是下面的数组对象)

但试试这个:

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;
} 

当你这样做时,老虎的价值也没有改变(只有在funk中创建的新数组c的内容)

您可以使用包装器通过ref模拟传递。 See this post.

虽然我对此没有任何意见

编辑只是为了好玩:

我修改了你的代码以使用上面发布的包装器。

它看起来很奇怪,但看起来很有效。

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

    }

}

打印

bird = 19
tiger = 14

: - S

答案 2 :(得分:4)

基本上,对象(如数组)通过“引用”传递给方法。因此,当您更改对象时,它会更改传递给方法的同一对象。

Primitives(如int)是“按值传递”,因此您在a中赋值的变量与传入的int变量不同。

我希望这会有所帮助......

答案 3 :(得分:0)

一个变量通过引用传递,另一个变量按值传递:)

What's the difference between passing by reference vs. passing by value?