【问题标题】:Passing only value for private members只为私有成员传递值
【发布时间】:2019-10-07 13:04:02
【问题描述】:

我正在创建一个类,其中一个数组作为其私有成员和 getter,setter 方法。我想使用主函数中的数组为该数组设置一个值。当我在主函数中操作数组时,它不应该影响该类中存在的数组。

我试过这段代码,但这里的数组被操纵了

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

【问题讨论】:

标签: java arrays pass-by-reference pass-by-value pass-by-rvalue-reference


【解决方案1】:

您可以在每次设置数组或需要返回其值时在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);
    }
}

旁注

补充阅读:

【讨论】:

    【解决方案2】:

    当您执行final ClassB cb2 = new ClassB(d); 时,您实际上是将数组b引用 传递给ClassB。由于两个引用相同,ClassB 中的数组正在发生变化。

    必读 - Is Java “pass-by-reference” or “pass-by-value”?

    如果您希望对d 所做的更改不影响ClassB 中的数组,您必须制作数组的副本。将您的构造函数更改为以下内容:

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

    注意:

    此外,使 ClassB 对象最终 (final ClassB cb2) 使其对象 cb2 成为不可变对象。不是里面的物体。

    因此,当您执行以下操作时,您无法更改cb2,但绝对可以更改cb2.a

    final ClassB cb2 = new ClassB(d);
    

    【讨论】:

      猜你喜欢
      • 2019-12-28
      • 1970-01-01
      • 2013-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-08
      相关资源
      最近更新 更多