effective java读书笔记二

来源:互联网 发布:个人业务网站源码 编辑:程序博客网 时间:2024/05/07 22:15

第3条:通过私有构造函数强化不可实例化的能力

对于某些工具类,比如java.lang.Math,java.util.Arrays,java.util.Collections可以把操作在实现特定接口的对象上的方法阻止起来。
但是这些类被实例化是没有任何意义的。
企图通过讲一个类做成抽象类来强制该类不能被实例化是行不通,因为该类的子类可以被实例化,并且可能会误导用户以为该类就是被设计用来继承的。
一个最简单的方法就是显示声明一个私有的构造函数,因为在不声明构造函数的时候编译器会为该类自动生成一个公有、无参的构造函数。
这样做的一个不好的后果就是该类不能被子类化。

第4条:避免创建重复的对象
1、如果一个对象是不变的,则它总是可以被重用。例如:String s = new String("silly");可以变成 String s = "silly";
2、除了重用非可变对象外,对于那些已知不会被修改的对象,也可以重用它们。
  class Person {       private final Date birthDate;       // Other fields omitted       public Person(Date birthDate) {           this.birthDate = birthDate;       }       // DON'T DO THIS!       public boolean isBabyBoomer() {           Calendar gmtCal =              Calendar.getInstance(TimeZone.getTimeZone("GMT"));           gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);           Date boomStart = gmtCal.getTime();           gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);           Date boomEnd = gmtCal.getTime();           return birthDate.compareTo(boomStart) >= 0 &&                birthDate.compareTo(boomEnd) < 0;       }   } 
 改进后版本:
class Person {       private final Date birthDate;       public Person(Date birthDate) {           this.birthDate = birthDate;       }       /**       * The starting and ending dates of the baby boom.       */       private static final Date BOOM_START;       private static final Date BOOM_END;       static {           Calendar gmtCal =              Calendar.getInstance(TimeZone.getTimeZone("GMT"));           gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);           BOOM_START = gmtCal.getTime();           gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);           BOOM_END = gmtCal.getTime();       }       public boolean isBabyBoomer() {           return birthDate.compareTo(BOOM_START) >= 0 &&                birthDate.compareTo(BOOM_END) < 0;       }   } 
 改善后的 Person class 只有在它被初始化的时候才惟次创建 Calendar, TimeZone, 和 Date 实体,而不再是每次 isBabyBoomer()被唤起就创建它们。如果isBabyBoomer()绝不会被调用,Person class改善版本将会没必要初始化 BOOM_START和BOOM_END字段。可以在 isBabyBoomer()第1次被调用是初始化它们。但是这种做法并不是很受推荐,因为这会使代码变得复杂,不太可能导致显著的效率提升。
注:如果初始化是很消耗资源的,懒初始化会明显提升效率吗???
3、有些情况并不像上面的情况那么明显。考虑 adapters(配接器),所谓适配器是这样的一个对象,他把功能委托给后面的对象,后面的对象提供一个可选的接口。由于适配器对象除了后面的对象没有其他的状态信息,所以针对某个给定对象的特定适配器而言,不需要创建多个适配器对象。比如:Map的keySet()返回一个包含Map所有键值的Set试图,对于给定的一个Map对象,这个Set在调用的时候不会重复创建。但是当Map发生改变时Set也会随之改变,因为KeySet是依附于Map对象的。
4、对于一些小对象的创建时非常廉价的,如果通过产生额外小对象能让程序的清晰、简介和功能强大往往也是很棒的件事情。反之,如果为了避免创建对象,因而自行维护自己的对象池,并不是一个好的做法,除非池物都是重量级对象(创建成本高昂,例如数据库连接)。
5、有些对象不能复用的,如果复用可能导致导致潜在错误和安全漏洞。而有些对象的复用代价比创建还大的时候也不应该复用。
原创粉丝点击