我对为什么我的私有变量被其他类暴露和修改感到困惑,这让我感到沮丧,因为我无法弄清楚我的概念/理解哪里出了问题。请帮忙。
Test.java
public class Test {
private String[] privateStringArr = new String[10];
Test() { }
public String[] getStringArr() {
String[] cover = privateStringArr;
return cover;
}
}
Main.java
public class Main {
static Test testClass = new Test();
static String[] shouldBePrivate = testClass.getStringArr();
public static void main(String[] args) {
System.out.println(testClass.getStringArr()[0]);
shouldBePrivate[0] = "hello";
System.out.println(shouldBePrivate[0]);
System.out.println(testClass.getStringArr()[0]);
}
}
输出:
null
hello
hello
为什么还要修改shouldBePrivate
中的privateStringArr
中的testClass
?
预先感谢
答案 0 :(得分:2)
因为您在此处返回了指向同一对象的链接
public String[] getStringArr() {
String[] cover = privateStringArr; // <- no new object is created
return cover;
}
您可以返回一份副本
public String[] getStringArr() {
return privateStringArr.clone();
}
答案 1 :(得分:1)
在public String[] getStringArr()
中,您向StringArr
传递了一个非私有引用:
public String[] getStringArr() {
String[] cover = privateStringArr;
return cover;
}
因此,您可以在主目录中对其进行修改。您需要返回privateStringArr
的真实副本。您可以使用clone()
或System.arrayscopy()
答案 2 :(得分:1)
执行以下步骤之后:
static String[] shouldBePrivate = testClass.getStringArr();
对shouldBePrivate
的所有修改都会影响privateStringArr
,因为它们是对同一数组对象的引用。两个变量都引用相同的数组。如果您修改数组,则两个变量都会受到影响。
为了避免这种情况,应在return Arrays.copyOf(privateStringArr , privateStringArr .length);
返回getStringArr()
答案 3 :(得分:1)
在Java中,几乎所有内容(诸如int
或char
之类的原始值除外)都是 reference 或 pointer -变量中存储的内容不是值本身,而是实际数据在内存中的地址。
cover = privateStringArr
shouldBePrivate = testClass.getStringArr()
这两个分配不复制Java中的实际数据-它们只是复制数据所在的内存中的地址。
private String[] privateStringArr = new String[10]; // create an array of 10 Strings, and store the address in privateStringArr
String[] cover = privateStringArr; // copy address to cover
return cover; // return the address stored in cover
String[] shouldBePrivate = testClass.getStringArr();// copy returned address to shouldBePrivate
shouldBePrivate[0] = "hello"; // find the data at address read from shouldBePrivate and modify it's first element
testClass.getStringArr()[0] // find the data at address returned from getStringArr() and read the first element