吉祥物生产:Effective Java 笔记(五)

来源:百度文库 编辑:中财网 时间:2024/05/07 05:17:35

为了使一个类成为非可变类,要遵循下面五条规则:

①不要提供任何会修改对像的方法;

②保证没有可被子类改写的方法;

③使所有的域都是final的;

④使所有的域都成为私有的;

⑤保证对于任何可变组件的互斥访问。(如果一个类指向可变对象的域,则必须确保该类的客 户无法活得指向这些对象的引用,并且永远不要用客户提供的对象引用来初始化这样的域,也不要在任何一个访问方法中返回该对象的引用);

以上规则比真正的要求强了一点,为了提高性能可以有所方式,如:保证没有一个方法能够对对象的状态产生外部可见的改变,许多非可变的类拥有一个或者多个非final的冗余域,把一个开销昂贵的计算结果缓存在这些域中。
非可变对象本质上是线程安全的,它们不要求同步。非可变对象可以被自由地共享。你不仅可以共享非可变对象,甚至也可以共享它们的内部信息。非可变对象为其他对象--无论是可变的还是不可变的--提供了大量的构件。

非可变类真正唯一的缺点是,对于每一个不同的值都要求一个单独的对象。String就是这样的。通常有个解决的办法就是提供一个帮助类来弥补,例如StringBuffer类。
如果一个类不能被做成非可变类,那么你仍然应该尽可能地限制它的可变性。
构造函数应该创建完全初始话的对象,所有的约束关系应该在这时候建立起来,构造函数不应该吧“只构造看一部分的实例”传递给其他的方法,不应该在后者函数之外子踢狗一个公有的初始化方法。

使一个类成为非可变类有如下三种方法:

①将一个类声明为final类型的;

②让该类中的每一个方法都成为final的,这种方法的好处在于其子类可以继续扩展新的方法;

③把类的构造函数声明为私有的或者包级私有的,增加静态工厂方法,来代替公有的构造函数;(该方法虽然不常用,但却是最值得推荐的)

 

NO.14 复合优先于继承
       实现代码重用最重要的办法就是继承,但是继承破坏了封装,导致软件的键壮性不足。如果子类继承了父类,那么它从父类继承的方法就依赖父类的实现,一旦他改变了会导致不可预测的结果。如果子类和超类在不同的包中,并且超类并不是为了扩展而设计的,那么继承会导致脆弱性。作者介绍了InstrumentedHashSet作为反例进行说明,原因就是没有明白父类的方法实现。作者给出的解决办法是通过化合来代替继承,尤其是当存在一个适当的接口来实现一个包装类的时候,用包装类和转发方法来解决问题。把想扩展的类作为本类的一个private final得成员变量。把方法参数传递给这个成员变量并得到返回值。这样做的缺点是这样的类不适合回掉框架。继承虽然好,我们却不应该滥用,只有我们能确定它们之间是is-a得关系的时候才使用。