繁体   English   中英

Java中可变对象的封装

[英]Encapsulation for mutable objects in Java

我正在学习“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
}

哪行代码打破了封装? 答案:第9行。“当封装像ArrayList这样的可变对象时,你的getter必须返回对对象副本的引用,而不仅仅是对原始对象的引用”。

我没有理解解释或如何修改原始代码。

所以在getList()而不是

return list;

我们应该这样做吗?

ArrayList<Integer> list2=list;
return list2;

你会替换:

return list;

有:

return new ArrayList<Integer>(list);

否则客户可以做...

foo.getList().add(5);

打破封装。

we do this?

ArrayList<Integer> list2=list;
return list2;

不,它说的是对象的副本,而不是引用的副本。

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

或者如所指出的, ArrayList有一个复制构造函数,它将另一个列表中的所有元素添加到新列表中。 以上三行主要是为了明确正在做什么。

您可以使用复制构造函数

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

将返回对您的私有ArrayList列表的引用,这是封装中断的地方。

ArrayList<Integer> list2=list;
return list2;

即使在这里,你只是将列表的引用传递给list2你可以尝试 -

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

暂无
暂无

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

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