私有变量获取 exposed/modified

Private variable getting exposed/modified

我很困惑为什么我的私有变量会被其他 类 公开和修改,这让我很沮丧,因为我无法弄清楚我的 concept/understanding 哪里出了问题。请帮忙。

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 也会修改 testClass 中的 privateStringArr

提前致谢

public String[] getStringArr() 中,您正在传递对 StringArr 的非私有引用:

public String[] getStringArr() {
    String[] cover = privateStringArr;
    return cover;
}

所以在你的主要部分你可以修改它。您需要 return privateStringArr 的真实副本。您可以使用 clone()System.arrayscopy()

因为你return一个link到这里的同一个对象

public String[] getStringArr() {
        String[] cover = privateStringArr; // <- no new object is created
        return cover;
    }

您可以return复制一份

public String[] getStringArr() {
        return privateStringArr.clone();
    }

经过以下步骤:

static String[] shouldBePrivate = testClass.getStringArr();

shouldBePrivate 的所有修改都会影响 privateStringArr,因为它们是对同一数组对象的引用。两个变量都引用同一个数组。如果修改数组,两个变量都会受到影响。

为了避免它,return Arrays.copyOf(privateStringArr , privateStringArr .length);应该在getStringArr()

返回

在 Java 中,几乎所有内容(除了像 intchar 这样的原始值)都是 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