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)
因为java中的字符串是不可变的.对字符串执行的每个"更改"都不会更改原始字符串,但会创建一个新的String对象.
首先,声称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你的方法中是从未见过它的外面.