Lon*_*man 19 java design-patterns
我正在阅读约书亚布洛赫的"有效Java",第39项制作防御性副本,我有一些问题.我总是使用以下构造:
MyObject.getSomeRef().setSomething(somevalue);
Run Code Online (Sandbox Code Playgroud)
这是短的:
SomeRef s = MyClass.getSomeRef();
s.setSomething();
MyObject.setSomeRef(s);
Run Code Online (Sandbox Code Playgroud)
它总是有效,但我想如果我getSomeRef()正在返回副本,那么我的快捷方式将不起作用,MyObject如果使用快捷方式是否安全,我怎么知道隐藏的实现是否隐藏?
JB *_*zet 27
你违反了两个OO编程规则:
请注意,这些规则只是规则,有时它们可以甚至必须被破坏.
但是,如果某个数据由一个对象拥有,并且该对象应该保证它拥有的对象上有一些不变量,那么它就不应该将其可变内部数据结构暴露给外部.因此需要一个防御性的副本.
另一个常用的习惯用法是返回可变数据结构的不可修改的视图:
public List<Foo> getFoos() {
return Collections.unmodifiableList(this.foos);
}
Run Code Online (Sandbox Code Playgroud)
例如,如果您必须确保对列表的每个修改都通过对象,那么这个成语或防御性复制惯用语可能很重要:
public void addFoo(Foo foo) {
this.foos.add(foo);
someListener.fooAsBeenAdded(foo);
}
Run Code Online (Sandbox Code Playgroud)
如果你不防守副本或返回列表的不可修改视图,呼叫者可以直接在富添加到列表中,而听者将不会被调用.
Mar*_*ers 10
文档是您(应该)知道的方式. MyObject应该记录它所暴露的东西是否可以或应该用来修改MyObject自己. 您应该只以类明确授予的方式修改对象.
例如,以下是两个方法的Javadoc List,其中一个结果不能用于更改List,一个结果可以更改List:
toArray():
返回的数组将是"安全的",因为此列表不会保留对它的引用.(换句话说,即使此列表由数组支持,此方法也必须分配新数组).因此调用者可以自由修改返回的数组.
subList():
返回的列表由此列表支持,因此返回列表中的非结构更改将反映在此列表中,反之亦然.返回的列表支持此列表支持的所有可选列表操作.
我会说文档中的沉默意味着你不应该使用它来改变对象(仅用于只读目的).
| 归档时间: |
|
| 查看次数: |
9672 次 |
| 最近记录: |