14

我有一个关于更改 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

4 回答 4

18

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

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

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

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

于 2009-01-28T23:45:00.523 回答
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;
} 

当你这样做时,你的 Tiger 的值也不会改变(只有在 funk 中创建的新数组 c 的内容)

您可以使用包装器模拟通过 ref 传递。看到这个帖子。

虽然我对此没有任何评论

编辑只是为了好玩:

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

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

// 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

于 2009-01-28T23:47:39.100 回答
4

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

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

我希望这有帮助...

于 2009-01-28T23:49:20.593 回答
0

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

按引用传递与按值传递有什么区别?

于 2013-11-09T15:30:16.217 回答