为什么我可以在 Java 中使用 getter 设置私有 class 属性的值?

Why can I set the value of a private class attribute with getter in Java?

我是 Java 的新手,我想知道为什么可以通过这种方式设置私有属性的值,而无需使用 setter ? :

class Example {
   private int[] thing;
   public void initialize() {
       thing = new int[10];
   }
   public int[] getThing() { 
       return thing;
   }
}
class myclass {
   public static void main(String args[]) {
       Example e = new Example();
       e.initialize();
       e.getThing()[0] = 1;
       System.out.println(e.getThing()[0]) // value is still 1...
}

我真的不明白为什么这是合法的...

编辑:我预计 e.getThing() 到 return thing 的值不是对 thing 的引用,即使是这样,因为 "thing" 是私有的我想我无法直接修改。

您公开了对来自 getter 的数组的引用,并且数组内容本身是 可变的 即您可以更改它们。因此,在上面的示例中,您 return 对 class 中私有变量持有的数组的引用,您修改了该数组,并且该更改将通过 getter 向前可见,因为它总是 return 修改数组。

为了避免这种情况,您可以做的是:

  1. return 通过您的 getter 收集的只读视图。这可能很快,但是如果父对象在您(比如说)迭代它时更改了您下面的数组内容,那么这可能会令人困惑
  2. return 防御副本 通过你的 getter。这意味着 return 每次调用都会复制一个新的数组副本,这不会在您的情况下发生变化,但是您需要为每次调用复制它支付费用

在上面的 specific 示例中,您可以在 initialize() 方法中创建一个只读集合,这样就不会出现此问题。

我认为你需要清楚重新。 private(即引用变量在 class 之外不可用)和 mutable(你的对象 return荷兰国际集团可以改变)。这是两个截然不同的概念。

private int[] thing;

表示对 thing 的引用是私有的,因此无法从 class 外部访问。幸运的是,你有一个getter所以你得到了参考。

由于数组是可变的,您可以修改数组的内容。

不能做的是设置新的thing:

e.thing = new int[5];

这就是 private 所做的。

thing 是私有的这一事实意味着您不能

Example e = new Example();
e.thing = new int[10];

但是,您已选择公开公开 initialize,因此您可以从另一个 class 调用它。 initialize 的实现细节只有 Example class 的作者知道。该作者可以在 class 内做任何他或她想做的事,包括用 private 个字段做任何他或她想做的事。

这是因为私有成员只能在 class 中直接访问,除非您提供一些 public 访问器方法,否则您不能在 class 之外访问它们。您正在为数组引用提供 public 访问器,并在获取引用后更改值