私有变量被暴露/修改

时间:2018-10-15 19:43:25

标签: java private public

我对为什么我的私有变量被其他类暴露和修改感到困惑,这让我感到沮丧,因为我无法弄清楚我的概念/理解哪里出了问题。请帮忙。

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

预先感谢

4 个答案:

答案 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中,几乎所有内容(诸如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