如果修改了char[]
数组,String
并不会改变
public class Main {
public static void main(String[] args) {
char[] cs = "Hello".toCharArray();
String s = new String(cs);
System.out.println(s);
cs[0] = 'X';
System.out.println(s);
}
}
输出:
Hello
Hello
这是因为通过new String(char[])
创建新的String
实例时,它并不会直接引用传入的char[]
数组,而是会复制一份,所以,修改外部的char[]
数组不会影响String
实例内部的char[]
数组,因为这是两个不同的数组。
从String
的不变性设计可以看出,如果传入的对象有可能改变,我们需要复制而不是直接引用。
例如,下面的代码设计了一个Score
类保存一组学生的成绩:
// int[]
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] scores = new int[] { 88, 77, 51, 66 };
Score s = new Score(scores);
s.printScores();
scores[2] = 99;
s.printScores();
}
}
class Score {
private int[] scores;
public Score(int[] scores) {
this.scores = scores;
}
public void printScores() {
System.out.println(Arrays.toString(scores));
}
}
输出:
[88, 77, 51, 66]
[88, 77, 99, 66]
观察两次输出,由于Score
内部直接引用了外部传入的int[]
数组,这会造成外部代码对int[]
数组的修改,影响到Score
类的字段。如果外部代码不可信,这就会造成安全隐患。
请修复Score
的构造方法,使得外部代码对数组的修改不影响Score
实例的int[]
字段。
// int[]
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] scores = new int[] { 88, 77, 51, 66 };
Score s = new Score(scores);
s.printScores();
scores[2] = 99;
s.printScores();
}
}
class Score {
private int[] scoreAll;
public Score(int[] scoreAll) {
int[] ints = new int[scoreAll.length];
for (int key = 0; key < scoreAll.length; key++) {
ints[key] = scoreAll[key];
}
System.out.println(ints);
this.scoreAll = ints;
}
public void printScores() {
System.out.println(Arrays.toString(scoreAll));
}
}
输出:
[88, 77, 51, 66]
[88, 77, 51, 66]