Effective Java 1

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.

原文地址:https://www.cnblogs.com/WutingjiaWill/p/9139520.html