尽管String是一个字符数组,但为什么String不能作为"按引用传递"

tub*_*bby -1 java arrays string pointers pass-by-reference

我理解在将数组asn参数传递给函数,并对函数内部的数组元素进行一些更改时,更改也将反映在调用函数中,因为数组直接在内存上运行(通过引用调用)

但是,为什么同样的行为不适用于字符串?因为String基本上是一个字符数组,所以我也期待Strings以同样的方式工作.

请参阅下面的代码.我将一个String(字符数组)以及一个int数组传入函数并对其进行一些更改.在main中打印这些时,我看到String保持不受影响,而反映了对数组的更改.

import java.util.Arrays;

public class TestString
{
    public static void main(String[] args)
    {
        String s = "hello";
        int[] a  = new int[5];
        Arrays.fill(a, -1);

        fun(s,a);

        System.out.println(s);
        System.out.println(a[0]);
    }

    static void fun(String s, int[] a)
    {
        s = "world";
        a[0] = 99;
    }
}
Run Code Online (Sandbox Code Playgroud)

产量

hello
99
Run Code Online (Sandbox Code Playgroud)

Jan*_*son 5

因为java中的字符串是不可变的.对字符串执行的每个"更改"都不会更改原始字符串,但会创建一个新的String对象.

  • 没有"对字符串进行更改"这样的事情.你不能改变一个字符串.这就是"不可变"的意思.当你说"改变完成一个字符串"时,你正在谈论改变一个字符串_variable_.你知道你在说什么,这里所有经验丰富的开发人员都知道你在说什么,但是菜鸟没有.菜鸟仍然在学习对象和变量之间的区别.给他一点帮助. (3认同)

Rea*_*tic 5

首先,声称a String是一个字符数组的说法是错误的.阿String是一个对象,其具有方法和设计具体不允许在其被所作的任何更改.

其次,你正在做的是不改变参数的某些元素.您正在更改参数变量.参数变量基本上是一个局部变量,它接收作为参数传递的字符串的引用.这样做:

s = "world";
Run Code Online (Sandbox Code Playgroud)

不更改传递的字符串.它用s新字符串替换局部变量的内容.由于Java 总是按值传递,因此不会在方法之外反映出来.如果你有这样的话会是一样的:

a = new int[30];
Run Code Online (Sandbox Code Playgroud)

在方法内部.在它之外你仍然会看到int[]你传递的5元素.

a[0] = 99;
Run Code Online (Sandbox Code Playgroud)

正在更改数组中的元素.所以它查看a,检查它引用的内容,转到该引用的数组,并更改其第0个元素.

由于String设计为不可变的,因此无法在其中执行类似的操作.你做不了类似的事情:

s.setCharacter(0,'a'); // This doesn't exist in Java
Run Code Online (Sandbox Code Playgroud)

但你可以用可变对象做到这一点.例如,如果你有:

public static void manipulateStringBuilder( StringBuilder sb ) {
    sb.append(": manipulated");
    sb = new StringBuilder("New value assigned");
}
Run Code Online (Sandbox Code Playgroud)

然后你可以这样写:

StringBuilder sb = new StringBuilder("My string");
System.out.println(sb);
manipulateStringBuilder( sb );
System.out.println(sb);
Run Code Online (Sandbox Code Playgroud)

输出将是:

My string
My string: manipulated

这是因为StringBuilder是一个可变的对象,加之与你的价值的事实,分配sb你的方法中是从未见过它的外面.