简体   繁体   English

Java中可变对象的封装

[英]Encapsulation for mutable objects in Java

I was studying the "Java SE 7 Programmer I & II Study Guide" and I did not understand the explanation below. 我正在学习“Java SE 7程序员I和II学习指南”,我不明白下面的解释。

class Fortress{
  private String name;
  private ArrayList<Integer> list;

  Fortress() {list=new ArrayList<Integer>;

  String getName{return name;}
  void addToList(int x){list.add(x);}
  ArrayList getList(){return list;} // line 1
}

Which lines of code break encapsulation? 哪行代码打破了封装? Answer: line 9. "When encapsulating a mutable object like an ArrayList, your getter must return a reference to a copy of the object, not just the reference to the original object". 答案:第9行。“当封装像ArrayList这样的可变对象时,你的getter必须返回对对象副本的引用,而不仅仅是对原始对象的引用”。

I did not either understand the explanation or how to modifiy the original code. 我没有理解解释或如何修改原始代码。

So in the getList() instead of 所以在getList()而不是

return list;

Should we do this? 我们应该这样做吗?

ArrayList<Integer> list2=list;
return list2;

You would have replace: 你会替换:

return list;

with: 有:

return new ArrayList<Integer>(list);

Otherwise the client can do... 否则客户可以做...

foo.getList().add(5);

breaking encapsulation. 打破封装。

we do this?

ArrayList<Integer> list2=list;
return list2;

No, it says a copy of the object, not a copy of the reference. 不,它说的是对象的副本,而不是引用的副本。

ArrayList<Integer> list2= new ArrayList<>();
list2.addAll( list );
return list2;

Or as pointed out, ArrayList has a copy constructor that will add all elements from another list to the new list. 或者如所指出的, ArrayList有一个复制构造函数,它将另一个列表中的所有元素添加到新列表中。 The above three lines are intended primarily to be clear what is being done. 以上三行主要是为了明确正在做什么。

您可以使用复制构造函数

return new ArrayList<Integer>(list);
return list;

would return the reference to your private ArrayList list this is where the encapsulation breaks. 将返回对您的私有ArrayList列表的引用,这是封装中断的地方。

ArrayList<Integer> list2=list;
return list2;

Even here also you are simply passing the reference of your list to list2 You can try - 即使在这里,你只是将列表的引用传递给list2你可以尝试 -

ArrayList<Integer> list2 = new ArrayList<Integer>();
list2.addAll(list);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM