为什么我可以在Java中使用Getter设置私人类属性的值



我是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()返回事物的价值而不是对事物的参考,即使是这种情况,因为"事物"是私人的,我认为我无法直接修改它。

您正在揭露getter对数组的引用,并且数组内容本身是 cutable ,即您可以更改它们。因此,在上面的示例中,您返回对班级私人变量持有的数组的引用,您对该数组进行修改,并且该更改将通过getter向前看,因为它总是返回修改的数组。

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

  1. 通过您的Getter返回收集的只读视图。这可能很快,但是如果父对象在(说)迭代时会更改您的数组内容,那么这可能会使您感到困惑
  2. 通过您的Getter返回防御副本。这意味着要返回每个呼叫的新数组副本,这不会在您的下面改变,但是您为每个呼叫复制
  3. 付费

在您的特定示例中,您可以在initialize()方法中创建一个只读集合,然后您将不会遇到此问题。

我认为您需要清楚。 private (即,参考变量在类之外不可用)和 Mutable (您要返回的对象可以更改)。这是两个非常不同的概念。

private int[] thing;

说对thing的引用是私人的,因此无法从班级外部访问。幸运的是,您有一个Getter,因此您可以获得参考。

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

您的不能做做的是设置新的thing

e.thing = new int[5];

这就是 private 做的。

这是因为私人成员只能在定义的课堂中直接访问,除非您提供某些公共访问方法,否则您无法在课堂之外访问它们。您正在提供数组参考的公共登录器,并在获得参考后,您将更改值

thing是私有的事实,您不能

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

但是,您选择公开公开露出initialize,因此您可以从其他类调用它。initialize的实现详细信息仅适用于Example类的作者。该作者可以在该课程中做任何他或她想做的事,包括在private字段中做任何他或她想要的事情。

最新更新