有效的Java防御性副本 [英] Defensive copy from Effective Java
问题描述
MyObject.getSomeRef()。setSomething(somevalue);
哪个是:
SomeRef s = MyClass.getSomeRef();
s.setSomething();
MyObject.setSomeRef(s);
它始终有效,但我猜,如果我的 getSomeRef()
正在返回副本,那么我的快捷方式将无法正常工作,如果可以安全使用快捷方式,是否隐藏了 MyObject
的实现是否隐藏?
您违反了OO编程的两个规则:
- 不要和陌生人交谈
- 封装
请注意,规则只是规则,它们可以甚至必须被打破。
但是如果一些数据是由一个对象拥有的,而该对象应该保证一些对它拥有的对象不变量,那么它不应该将其可变内部数据结构暴露给外部。因此,需要一个防御性副本。
另一个常用的成语是返回可变数据结构的不可修改的视图:
public List< Foo> getFoos(){
return Collections.unmodifiableList(this.foos);
}
这个成语或防御性复制成语可能很重要,如果您必须确保列表中的每个修改都会通过对象:
public void addFoo(Foo foo){
this.foos.add(foo);
someListener.fooAsBeenAdded(foo);
}
如果您没有制作防御性副本或返回不可修改的视图列表,调用者可以直接向列表中添加一个foo,并且不会调用监听器。
I am reading "Effective Java" by Joshua Bloch, item 39 make defensive copy, and I have some questions. I always use the following construct:
MyObject.getSomeRef().setSomething(somevalue);
which is short for:
SomeRef s = MyClass.getSomeRef();
s.setSomething();
MyObject.setSomeRef(s);
It always works, but I guess if my getSomeRef()
was returning a copy then my shortcut would not work, how can I know if the implementation of MyObject
is hidden if it is safe to use a shortcut or not?
You're violating two rules of OO programming:
- do not talk to strangers
- encapsulation
Note that these rules are just rules, and that they can, or even must be broken sometimes.
But if some data is owned by an object, and the object is supposed to guarantee some invariants on the objects it owns, then it should not expose its mutable internal data structures to the outside. Hence the need for a defensive copy.
Another often used idiom is to return unmodifiable views of the mutable data structures:
public List<Foo> getFoos() {
return Collections.unmodifiableList(this.foos);
}
This idiom, or the defensive copy idiom, can be important, for example, if you must make sure that every modification to the list goes through the object:
public void addFoo(Foo foo) {
this.foos.add(foo);
someListener.fooAsBeenAdded(foo);
}
If you don't make a defensive copy or return an unmodifiable view of the list, a caller could add a foo to the list directly, and the listener would not be called.
这篇关于有效的Java防御性副本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!