为什么这两个Java程序的输出结果不同

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传递方法参数的方式中缺少了一些东西。我知道对象引用是按值传递的,但是我无法将我的理解与这些程序的结果调和。

2
Java是按值传递(pass by value),而不是按引用传递。 - Pshemo
6个回答

8
在“2”版本中,“change”方法“无效”,因为您正在将一个新数组赋值给本地(参数)变量“a”。这对于在主方法中声明的变量“a”分配的数组没有影响。
当“change()”方法完成时,新数组将超出范围且无法访问(因此被标记为垃圾回收)。

1
因此,除非重新分配参数可以使代码看起来更清晰,否则您应该考虑它是一种不良实践。 - Daniel Kaplan

4

这是因为Java按值传递参数,而不是按引用传递。在引用的情况下,你只会复制该引用。你可以修改引用后面的值(第一种情况),但不能修改引用本身(第二种情况)。


2

在调用此函数时,

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

发生的只是局部于方法的变量a被分配了一个新的引用,这不会对你主方法中引用旧数组的变量a产生任何影响。


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引用了一个新数组,而原始数组仍然被原始引用。

1
这是因为您传递数据的方式不同。在第一个示例中,由于您将数组的地址传递给Change()方法,该方法更改了地址中的数据,因此数组发生了更改。
在第二个示例中,确实传递了数组,但您初始化了一个新数组,声明了新的内存空间并更改了传递的地址。但是,这并不会删除主方法中声明和初始化的原始char[]实例,因此当您打印它时,它会打印出本地char[]而不是您尝试创建的新char[]。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接