3
public class Test {

    public static void change(char[] a){
        a[0] = '1';
        a[1] = '2';
    }

    public static void main(String args[]){
        char[] a = new char[]{'a','b'};

        change(a);

        System.out.println(a);
    }

}

输出为 12

public class Test {

    public static void change(char[] a){
        a = new char[]{'1','2'};
    }

    public static void main(String args[]){
        char[] a = new char[]{'a','b'};

        change(a);

        System.out.println(a);
    }

}

输出为 ab。我知道我遗漏了一些关于 java 传递方法参数的方式。我知道对对象的引用是按值传递的。但是,我无法将我的理解与这些程序的结果相协调。

4

6 回答 6

8

在版本“2”中,change 方法“什么都不做”,因为您将一个新数组分配给a,这是本地(参数)变量 aa这对分配给在 main 方法中声明的变量的数组没有影响。

change()当方法完成时,新数组超出范围并且不可访问(因此指定用于垃圾收集) 。

于 2013-02-09T01:31:04.113 回答
4

这是因为 Java 按值传递,而不是按引用传递。在引用的情况下,您复制引用。您可以修改引用后面的值(版本 1),但不能修改引用本身(版本 2)。

于 2013-02-09T01:31:54.020 回答
2

随着调用

a = new char[]{'1','2'};

所发生的只是方法的本地变量被分配了一个新的引用,这对仍然引用旧数组的 main 方法中a的变量没有任何影响。a

于 2013-02-09T01:32:08.763 回答
1

因为 Java 通过不是引用在方法之间传递对象。在第一个示例中,您在 main 中实例化一个对象并将其传递给change,它仅通过设置值来更改它。在第二个示例中,您实际上在change (using new) 中重新实例化了它,因为您已经在主体中实例化了一次。char[]重新实例化的范围change仅是方法,因此当您返回调用它的 main 时,它将恢复到自己的实例,而不是本地使用的实例change

于 2013-02-09T01:38:41.097 回答
1

第一个,您正在更改传入并由“a”引用的数组

第二个,您正在更改“a”引用的数组

有效地,你正在做的第二个

char[] original = new char[]{'a','b'};
// this is basically what your function call is doing from here....
char[] a = original;      // a is now also referencing the ab array
a = new char[]{'1','2'};  // now a is referencing a 1 2 array.
// then the function returns....and original is the same still

所以 a 引用了一个新数组,而原始数组仍然引用了原始数组

于 2013-02-09T01:30:58.437 回答
1

发生这种情况是因为您传递数据的方式。在第一个示例中,数组已更改,因为您向 Change() 方法传递了数组的地址,并且该方法正在更改地址中的数据。

在第二个示例中,数组被传递,但是您正在初始化一个新数组,该数组声明新的内存空间并更改传入的地址。但是,这不会删除主中原始声明和初始化的 char[] 实例方法,因此当您打印出来时,它会打印出本地 char[] 而不是您尝试创建的新字符。

于 2013-02-09T01:34:21.490 回答