我正在阅读“Java Concurrency in Practice”一书,有一部分我不太了解。我知道这是一本旧书,可能就是为什么没有提到我的疑问。
在“共享对象”一章中,有一个名为“发布和转义”的部分:
发布对象意味着使其可用于其之外的代码 当前范围,例如通过存储对其他代码的引用 可以找到它,从非私有方法返回它,或将它传递给 另一个班级的方法......
发布时的对象 据说不应该逃脱。
还有一个例子:
class UnsafeStates
{
private String[] states = new String []
{"AK", "AL" ....};
public String [] getStates(){return states;}
}
以这种方式发布状态是有问题的,因为任何调用者都可以 修改其内容。在这种情况下,states数组已经逃脱了它 意图范围,因为本来应该是私人国家 有效地公开。
并且指定不以这种方式执行从不。
我突然想到封装概念,基本上就是说要做到这一点。
我误解了概念或什么?
答案 0 :(得分:1)
问题是这个方法:
public String [] getStates(){return states;}
返回您对states
数组的引用。
即使您将states
声明为私有,但如果您通过getStates()
方法获取,则仍可以修改states
变量:
UnsafeStates us = new UnsafeStates();
String[] copyStates = us.getStates();
copyStates[0] = "You don't know"; // Here the change to `copyStates` also affect the `states` variable since they're both reference to the same array.
通常,对于对象和数组属性,通常会返回该属性的深层副本以防止修改内部属性。
Ex:对于数组:
String[] copied = new String[states.length];
System.arraycopy(states, 0, copied, 0, states.length);
return copied;
列表:
return Collections.unmodifiableList(internalList);
对象:
return internalObject.clone(); // Require deep clone