说我有一个方法:
public String getString() {
char[] array = new char[]{'a', 'b', 'c'};
return new String(array);
}
数组是否仍然在 String 构造函数中复制,或者 Java 编译器是否足够聪明,可以识别数组中的元素不能更改,因此它只能引用数组?
谢谢
说我有一个方法:
public String getString() {
char[] array = new char[]{'a', 'b', 'c'};
return new String(array);
}
数组是否仍然在 String 构造函数中复制,或者 Java 编译器是否足够聪明,可以识别数组中的元素不能更改,因此它只能引用数组?
谢谢
由于 javaString
类是不可变的,因此构造函数必须复制数组。
否则有人可以持有对数组的引用并修改它:
char[] array = new char[]{'a', 'b', 'c'};
String string = new String(array);
array[1] = 'd'; // array modification must NOT affect the string
查看来源java.lang.String
:
/**
* Allocates a new {@code String} so that it represents the sequence of
* characters currently contained in the character array argument. The
* contents of the character array are copied; subsequent modification of
* the character array does not affect the newly created string.
*
* @param value
* The initial value of the string
*/
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
编辑:
另请参阅java.util.Arrays
which calls的来源System.arraycopy
。
看看这个构造函数:
153 public String(String original) {
154 this.value = original`.value;
155 this.hash = original.hash;
156 }
这将是一个字符串文字:
"abc"
这只是对String(char[] value)
作为 char 数组元素传入的 a、b、c 的调用。简而言之,String x = "abc"
这只是编译器为您提供的语法糖,以解决您在上面所做的事情。
答案应该很明显:为了String
保持不可变,它必须防御性地复制数组。
考虑这段代码:
public String getString() {
char[] array = new char[]{'a', 'b', 'c'};
String s = new String(array); // abc
array[0] = 'x';
return s; // xbc
}
如果未复制数组,则后备数组将泄漏,从而使 String 暴露于可变性。
如果你看到源代码,你就会得到答案。输入数组被复制而不被引用。这是源代码:
public String(char value[]) {
this.offset = 0;
this.count = value.length;
this.value = StringValue.from(value);
}
static char[] from(char[] value) {
return Arrays.copyOf(value, value.length);
}