Закрытая переменная становится доступной / модифицированной - PullRequest
0 голосов
/ 15 октября 2018

Меня смущает, почему мои личные переменные подвергаются и изменяются другими классами, и меня расстраивает то, что я не могу понять, где моя концепция / понимание пошло не так.Пожалуйста, помогите.

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 голосов
/ 15 октября 2018

В Java почти все (кроме простых примитивов, таких как int или char) - это ссылка или указатель - то, что хранится в переменной, не является самим значением,но адрес в памяти, где фактические данные.

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
0 голосов
/ 15 октября 2018

Поскольку вы возвращаете ссылку на тот же объект здесь

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

Вы можете вернуть копию вместо

public String[] getStringArr() {
        return privateStringArr.clone();
    }
0 голосов
/ 15 октября 2018

После следующего шага:

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

Все модификации в shouldBePrivate будут влиять на privateStringArr, поскольку они являются ссылками на один и тот же объект массива.Обе переменные ссылаются на один и тот же массив.Если вы измените массив, обе переменные будут затронуты.

Чтобы избежать этого, return Arrays.copyOf(privateStringArr , privateStringArr .length); должен быть возвращен в getStringArr()

0 голосов
/ 15 октября 2018

В public String[] getStringArr() вы передаете не приватную ссылку на StringArr:

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

Таким образом, вы можете изменить ее на своей главной странице.Вам необходимо вернуть истинную копию privateStringArr.Вы можете использовать clone() или System.arrayscopy()

...