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

时间:2016-12-27 14:51:50

标签: java class encapsulation

我是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()返回thing的值而不是对thing的引用,即使是这种情况,因为“thing”是私有的,我以为我不能直接修改它。

4 个答案:

答案 0 :(得分:8)

您从getter公开了对数组的引用,并且数组内容本身是 mutable ,即您可以更改它们。因此,在上面的示例中,您返回对类中私有变量所持有的数组的引用,您修改该数组,并且该更改将通过前进的getter可见,因为它始终返回该修改后的数组。

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

  1. 通过getter返回集合的只读视图。这可能很快,但是如果父对象改变你下面的数组内容,而你(比如说)迭代它,那么这可能会令人困惑
  2. 通过你的getter返回防御性副本。这意味着每次通话都会返回一个新的阵列副本,而且这不会发生变化,但是您为每次通话复制它都要付出代价
  3. 在上面的特定示例中,您可以在initialize()方法中创建只读集合,然后您就不会遇到此问题。

    我认为你需要清楚。 private (即引用变量在类外无法使用)和 mutable (您返回的对象可以更改)。这是两个非常不同的概念。

答案 1 :(得分:2)

private int[] thing;

表示对thing的引用是私有的,因此无法从课外访问。幸运的是,你有一个吸气剂,所以你得到参考。

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

无法做的是设置新的thing

e.thing = new int[5];

这就是私人所做的。

答案 2 :(得分:0)

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

答案 3 :(得分:-2)

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

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

但是,您已选择公开公开initialize,因此您可以从其他类调用它。 initialize的实现细节只有Example类的作者才能知道。该作者可以在该课程中做任何他或她想做的事情,包括用private字段做他或她想做的任何事情。