Item1 考虑用静态工厂方法代替构造器
1、优点
可读性强。
不会每次调用就通过构造器创建一个新的实例。
可以返回原始类型的任何子类型。
2、缺点
只有私有构造器无法被子类化。
Item 2 遇到多个构造器参数考虑用构建器Builder
1、什么是构建器?
1 public class Builder_Pattern { 2 private final int p1; 3 private final int p2; 4 private final int p3; 5 private final int p4; 6 7 public static class Builder{ 8 private final int p1; 9 private final int p2; 10 11 private int p3=0; 12 private int p4=0; 13 14 public Builder(int p1,int p2){ 15 this.p1=p1; 16 this.p2=p2; 17 } 18 public Builder p3(int val){ 19 p3=val; return this; 20 } 21 public Builder p4(int val){ 22 p4=val; return this; 23 } 24 public Builder_Pattern build(){ 25 return new Builder_Pattern(this); 26 } 27 } 28 29 private Builder_Pattern(Builder builder){ 30 p1=builder.p1;p2=builder.p2;p3=builder.p3;p4=builder.p4; 31 } 32 33 34 //Builder_Pattern bp=new Builder_Pattern.Builder(1,2).p3(1).p4(1).build(); 注意 p3 p4返回类型是Builder 可以连续调用! 35 }
2、使用构建器的好处。
在多参数时写法优雅,参数具有可读性,保证线程安全,适合类的继承。
3、使用构建器的坏处。
花费会更高,因此在参数有许多的时候建议使用,特别是有很多可选参数时。
Item 3 Singleton的最佳实现方式是枚举类型
1、什么是枚举类
1 public class EnumTest { 2 public static void main(String[] args) { 3 Scanner in=new Scanner(System.in); 4 System.out.println("put:"); 5 String input=in.next().toUpperCase(); 6 Size size=Enum.valueOf(Size.class,input); 7 System.out.println(size); 8 System.out.println(size.getAbbreviation()); 9 System.out.println(Size.SMALL.getAbbreviation()); 10 } 11 12 } 13 enum Size{ 14 SMALL("S"),MEDIUM("M"),LARGE("L"); 15 private String abbreviation; 16 private Size(String abbreviation){this.abbreviation=abbreviation;} 17 public String getAbbreviation(){return abbreviation;} 18 19 }
2、优点
提供序列化机制,甚至在反射机制下也能确保只有单例。
3、缺点
无法继承自除了Enum之外的超类以及其他子类进行继承。
Item 4 通过私有构造器强化不可实例化的能力
1、优点
在需要创建类似工具类等不需要实例化的类时,将构造器私有化,以保证该类在任何情况下都不会被实例化。
2、缺点
无法被继承
Item 5 使用依赖注入去连接资源
1、依赖注入
1 public class dependency { 2 private final String str; 3 public dependency(String str){ 4 this.str=str; 5 } 6 }
2、优点
对于一个行为由其他资源所参数化所决定的类来说,使用静态工具类或者单例是不适合的。而是应该当创建一个实例是将资源传入构造器。
Item 6 避免创建不必要的对象
1、优点
对于一些不会发生改变的变量或是常量,使用static块进行初始化,使某些类不会被重复创建,减少开销。例如 new String就是一个不好的习惯。
在构造器中使用静态工厂就是个不错的方法。重点是对静态的使用static(final)。自动装箱也很可能引起巨大的开销。
Item 7消除过期的对象引用
1、优点
例如对于Stack类中的数组当执行pop()操作后,被弹出的元素并不会自动被gc所回收。因此需要手动进行释放。
1 Object result = elements[--size]; 2 elements[size] = null; // Eliminate obsolete reference 3 return result;
当一个类自己进行内存的管理时,这种状况就尤其要注意。
进行缓存时也需要注意这个问题。
对于监听器以及回调操作,也需要注意。
Item 8 尽量避免使用Finalizers
1、优点
由于Finalizers的优先级很低,不能保证Finalizers何时会被调用,会导致内存开销的增加,并且会大幅降低程序的性能。
永远不要Finalizers来更新持久状态。
对含有Finalizers方法的类进行子类化会有严重的安全隐患。
使用try-with-resources作为某些资源的结束方法。并且对于其状态是否被关闭需要在私有域中进行记录。这样其他方法调用时可以对状态进行检测。
Finalizers有两种合理的用法:
1、在忘记调用close方法时作为一张安全网,但这也只是一个不得以的备用措施,仍然会造成很大开销,并且不知何时会进行。
2、native peer (?)
Item 9 更偏向使用 try-with-resources 块
1、try-with-resources
在try()中进行一个或多个的资源链接或读取。并且这些资源是必须被关闭的的,使用这个语法将会被自动关闭无需显示调用close方法。
在{}进行实际操作。
同样可以使用catch语句
1 static String firstLineOfFile(String path) throws IOException { 2 try (BufferedReader br = new BufferedReader( 3 new FileReader(path))){ 4 return br.readline(); 5 } 6 }
2、优点
可以同时打开多个资源,并保证被关闭,而无需显式调用close方法。
exception不会被覆盖,可以查看每个exception.