为什么函数在Java中修改数组[0]而不是字符串?

为什么函数在Java中修改数组[0]而不是字符串?,java,arrays,string,methods,Java,Arrays,String,Methods,代码 public class Foo { public static void main(String[] args) { //declaring and initializing String variable 'str' with value "outside" String str = "main"; //declaring and initializing Array 'array' with values

代码

public class Foo {

    public static void main(String[] args) {

        //declaring and initializing String variable 'str' with value "outside"
        String str = "main";

        //declaring and initializing Array 'array' with values
        String [] array = {"main"};

        //printing values of str and array[0]
        System.out.println("str : " + str + " , array[0] : " + array[0]);

        //calling function foo()
        foo(str, array);

        //printing values after calling function foo()
        System.out.println("str : " + str + " , array[0] : " + array[0]);
    }

    static void foo(String str, String[] array){
        str = "foo";
        array[0] = "foo";
    }

}
输出

str : main , array[0] : main  
str : main , array[0] : foo
问题


为什么字符串
str
保持与“main”相同,但调用函数
foo()
后,
array[0]
的值从“main”修改为“foo”?效果不应该相同吗?

这是因为数组的头指向内存中的对象。数组实际上只是对其他位置的引用。因此,当您修改数组时,您正在修改指向内存中对象的元素0。当您的方法退出时,您没有修改数组[0]引用,因此您指向内存中的同一点,您在该点上更改了对象

另一方面,当您将字符串指定为“foo”时,实际上只是在方法范围内更改它,因为您正在更改指向新字符串的指针。您必须返回字符串或将其重新分配给main方法中的引用,或者可以将字符串设置为一个字段,使其始终具有相同的引用

这个链接可能比我更好地解释它


这是因为数组的头指向内存中的对象。数组实际上只是对其他位置的引用。因此,当您修改数组时,您正在修改指向内存中对象的元素0。当您的方法退出时,您没有修改数组[0]引用,因此您指向内存中的同一点,您在该点上更改了对象

另一方面,当您将字符串指定为“foo”时,实际上只是在方法范围内更改它,因为您正在更改指向新字符串的指针。您必须返回字符串或将其重新分配给main方法中的引用,或者可以将字符串设置为一个字段,使其始终具有相同的引用

这个链接可能比我更好地解释它


不应该,因为Java是如何处理引用的

为方法提供两个参数:字符串(即字符串的地址)和数组(即数组的地址)。这些地址本地存储在
str
array
中,如果更改地址,则
main()的
str
array
方法之外的地址不会更改

然后创建一个字符串“foo”,并将其(或者更确切地说,它的地址)分配给local
str
。这对main()的str没有任何影响。但是,数组地址是本地的,但数组内的地址不是本地的。如果你愿意写

array = {"foo"};
这不会影响
main()
array
,但是

array[0] = "foo";

您可以更改作为引用的数组中的某些内容。

不,不应该这样做,因为Java是如何处理引用的

为方法提供两个参数:字符串(即字符串的地址)和数组(即数组的地址)。这些地址本地存储在
str
array
中,如果更改地址,则
main()的
str
array
方法之外的地址不会更改

然后创建一个字符串“foo”,并将其(或者更确切地说,它的地址)分配给local
str
。这对main()的str没有任何影响。但是,数组地址是本地的,但数组内的地址不是本地的。如果你愿意写

array = {"foo"};
这不会影响
main()
array
,但是

array[0] = "foo";

您更改了作为引用的数组中的某些内容。

在代码中,您将
str
作为
foo
的参数传递。在java中,当您将任何变量作为参数传递时,它将成为新的内容。在
foo
方法中更改
str
,只会更改
str
,而不会更改
main
str

但是对于
数组
,两个变量都从相同的数据中获取。这是因为数组是对象。当对象按值传递时,它会进行复制,但复制的对象仍然引用相同的数据


这里有更好的解释:

在您的代码中,您传递了
str
作为
foo
的参数。在java中,当您将任何变量作为参数传递时,它将成为新的内容。在
foo
方法中更改
str
,只会更改
str
,而不会更改
main
str

但是对于
数组
,两个变量都从相同的数据中获取。这是因为数组是对象。当对象按值传递时,它会进行复制,但复制的对象仍然引用相同的数据


这里有更好的解释:

字符串文字不能由您的方法更改,因为它是作为字符串文字按值传递的,但是数组可以,因为为该数组传递的值是它的引用,Java中的字符串必须是不可变的,不能修改字符串,因为它是不可变的对象。建议您使用StringBuffer。方法无法更改字符串文字,因为它是以字符串文字的形式通过值传递的,但数组可以,因为为该数组传递的值是它的引用,Java中的字符串必须是不可变的,不能修改字符串,因为它是不可变的对象。建议您使用StringBuffer