Передача только значения для частных членов - PullRequest
3 голосов
/ 21 мая 2019

Я создаю класс с одним массивом в качестве его закрытого члена и метода получения, метода установки для этого. Я хочу установить значение для этого массива, используя массив в основной функции. Когда я манипулирую массивом в основной функции, он не должен влиять на массив, присутствующий в этом классе.

Я попробовал этот код, но здесь с массивом манипулируют

class ClassB {

    private int[] a;

    ClassB() { }

    ClassB(int[] a) {
        this.a=a;
    }

    int[] geta() {
        return this.a;
    }

    void seta(int a[]) {
        this.a = a;
    }
}

public class ClassA{

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        System.out.println("Enter size : ");
        int n = sc.nextInt();
        int[] d = new int[n];
        System.out.println("Enter array elements : ");
        for (int i=0 ; i<n ; i++) {
            d[i] = sc.nextInt();
        }
        final ClassB cb2 = new ClassB(d);
        d[3] = 15;
        System.out.println("After changing array d : \n Values of array d :");
        for (int i=0 ; i<n ; i++) {
            System.out.println(d[i]);
        }
        System.out.println("Values of array a of cb2 :");
        int[] b = cb2.geta();
        for (int i=0 ; i<n ; i++) {
            System.out.println(b[i]);
        }
    }
}

Я ожидаю:

Enter size :

5

Enter array elements :
1
2
3
4
5
After changing array d :

 Values of array d :

1
2
3
15
5

Values of array a of cb2 :
1
2
3
4
5

Но фактический результат был:

Enter size :

5

Enter array elements :

1
2
3
4
5

After changing array d :

 Values of array d :

1
2
3
15
5

Values of array a of cb2 :

1
2
3
15
5

Ответы [ 2 ]

4 голосов
/ 21 мая 2019

Вы можете сделать защитных копий в ClassB каждый раз, когда вы устанавливаете массив или вам нужно возвращать его значения.Как это:

class ClassB {
    // ... code omitted for brevity

    ClassB(int[] a) {
        seta(a);
    }

    int[] geta() {
        int[] copy = new int[a.length];
        System.arraycopy(a, 0, copy, 0, a.length);
        return copy;
    }

    void seta(int a[]) {
        this.a = new int[a.length];
        System.arraycopy(a, 0, this.a, 0, a.length);
    }
}

Примечания * :

  • Если вы действительно хотите сделать ClassB неизменным, у вас не должно быть сеттера для егозначения.
  • Утилита System.arraycopy использовалась для создания копии массивов.Не стесняйтесь использовать здесь все, что лучше соответствует вашим потребностям (вы можете рассмотреть возможность использования a.clone(), предложенного Lino в комментарии ниже ... это хорошая тема по этому поводу: Почему clone () - лучший способ длякопирование массивов? ).

Дополнительные показания:

1 голос
/ 21 мая 2019

Когда вы делаете final ClassB cb2 = new ClassB(d);, вы по существу передаете ссылку массива b на ClassB.Поскольку обе ссылки одинаковы, массив внутри ClassB меняется.

Необходимо прочитать - Является ли Java «передачей по ссылке» или «передачей по значению»?

Вам нужно будет сделать копию массива, если вы хотите, чтобы изменения, внесенные в d, не влияли на массив внутри ClassB.Измените ваш конструктор на следующий:

ClassB(int[] a) {
    this.a = a.clone();
}

Примечание:

Кроме того, ClassB объект final (final ClassB cb2) делает его объектом cb2 как неизменный.Не предметы внутри него.

Следовательно, вы не можете изменить cb2, но определенно можете изменить cb2.a, если вы выполните следующее:

final ClassB cb2 = new ClassB(d);
...