Java理论与实践 - 它是谁的对象? - 编程入门网
布时的时间和 消费时的时间有任何延迟,那么订阅者看到的 previous5Bids 数组的值将不同 于消息发布时的时间,并且多个订阅者看到的前面投标的值可能会互不相同。在 这个例子中,订阅者将看到当前投标的历史值和前面投标的更接近现在的值,从 而形成了这样的错觉,认为前面投标比当前投标的值要高。不难设想这将如何引 起问题――这还不算,当应用在很大的负载下时,这样一个问题则更是暴露无遗 。使得消息类不可变并在构造时克隆像数组这样的可变引用,就可以防止该问题 。
清单 4. 发布-订阅式消息传递代码中的悬空数组别名
可变对象的指导 如果您要创建一个可变类 M,那么您应该准备编写比 M 是不可变的情况下多 得多的文档说明,以说明怎样处理 M 的引用。首先,您必须选择以 M 为参数或 返回 M 对象的方法是使用值语义还是引用语义,并准备在每一个在其接口内使 用 M 的其他类中清晰地文档说明这一点 。如果接受或返回 M 对象的任何方法 隐式地假设 M 的所有权被转移,那么您必须也文档说明这一点。您还要准备着 接受在必要时创建防御副本的性能开销。 一个必须处理对象所有权问题的特殊情况是数组,因为数组不可以是不可变 的。当传递一个数组引用到另一个类时,可能有创建防御副本的代价,除非您能 确保其他类要么创建了它自己的副本,要么只在调用期间保存引用,否则您可能 需要在传递数组之前创建副本。另外,您可以容易地结束这样一种情形,即调用 的两边的类都隐式地假设它们拥有数组,只是这样会有不可预知的结果出现。 结束语 处理可变的类比处理不可变的类需要更细心。当在方法之间传递对可变对象 的引用时,您需要清楚地文档说明哪些情况下对象的所有权被转移。而缺乏清楚 的文档说明时,您必须在方法调用的两边都创建防御副本。认为可变性更合理是 基于性能方面的考虑,因为不需要在每次状态改变时都创建一个新对象,然而, 由防御性复制所招致的性能代价能轻而易举地抵消掉因为减少了对象创建而节省 下来的性能。 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |