Java理论与实践: 变还是不变? - 编程入门网
T 事件类都没有作为严格的不变类来实现,而是可以有小小的修改。同样 地,在使用一定形式的消息传递以在组件间通信的系统中,使消息对象成为不变 的或许是明智的。
编写不变类的准则 编写不变类很容易。如果以下几点都为真,那么类就是不变的: 它的所有字段都是 final 该类声明为 final 不允许 this 引用在构造期间转义 任何包含对可变对象(如数组、集合或类似 Date 的可变类)引用的字段: 是私有的 从不被返回,也不以其它方式公开给调用程序 是对它们所引用对象的唯一引用 构造后不会更改被引用对象的状态 最后一组要求似乎挺复杂的,但其基本上意味着如果要存储对数组或其它可 变对象的引用,就必须确保您的类对该可变对象拥有独占访问权(因为不然的话 ,其它类能够更改其状态),而且在构造后您不修改其状态。为允许不变对象存 储对数组的引用,这种复杂性是必要的,因为 Java 语言没有办法强制不对 final 数组的元素进行修改。注:如果从传递给构造函数的参数中初始化数组引 用或其它可变字段,您必须用防范措施将调用程序提供的参数或您无法确保具有 独占访问权的其它信息复制到数组。否则,调用程序会在调用构造函数之后,修 改数组的状态。清单 3 显示了编写一个存储调用程序提供的数组的不变对象的 构造函数的正确方法(和错误方法)。 清单 3. 对不变对象编码的正确和错误方法
通过一些其它工作,可以编写使用一些非 final 字段的不变类(例如, String 的标准实现使用 hashCode 值的惰性计算),这样可能比严格的 final 类执行得更好。如果类表示抽象类型(如数字类型或颜色)的值,那么您还会想 实现 hashCode() 和 equals() 方法,这样对象将作为 HashMap 或 HashSet 中 的一个键工作良好。要保持线程安全,不允许 this 引用从构造函数中转义是很 重要的。 偶尔更改的数据 有些数据项在程序生命期中一直保持常量,而有些会频繁更改。常量数据显 然符合不变性,而状态复杂且频繁更改的对象通常不适合用不变类来实现。那么 有时会更改,但更改又不太频繁的数据呢?有什么方法能让 有时更改的数据获 得不变性的便利和线程安全的长处呢? util.concurrent 包中的 CopyOnWriteArrayList 类是如何既利用不变性的 能力,又仍允许偶尔修改的一个良好示例。它最适合于支持事件监听程序的类( 如用户界面组件)使用。虽然事件监听程序的列表可以更改,但通常它更改的频 繁性要比事件的生成少得多。 除了在修改列表时, CopyOnWriteArrayList 并不变更基本数组,而是创建 新数组且废弃旧数组之外,它的行为与 |
凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢! |