effective-java:创建和销毁对象
第一条:考虑使用静态工厂方法代替构造器
- 静态工厂方法有名字,可以通过方法名字准确的了解想要创建的对象的详情,例如:输入的参数等。
- 在静态方法里可以写逻辑,所以可能不必每次调用都会创建一个新的对象。
- 不必返回此对象的实例,也可以根据自己的需要返回此对象的子类的实例。
- 在创建参数化类型实例的时候,他们使代码变得根据简洁。
第二条:遇到多个构造器参数时要考虑用构建器
下面代码为构建器示例:
package createOrdestoryObject;
public class Clothes {
private String name = "";
private String color = "";
private int size = 0;
private double price = 0.00;
public Clothes(Builder builder){
this.name = builder.name;
this.color = builder.color;
this.size = builder.size;
this.price = builder.price;
}
public static class Builder{
private String name = "";
private int size = 0;
private String color ;
private double price = 0.00;
public Builder(String name ,int size){
this.name = name;
this.size = size;
}
public Builder Color(String color){
this.color = color;
return this;
}
public Builder Price(double price){
this.price = price;
return this;
}
public Clothes build(){
return new Clothes(this);
}
}
public static void main(String[] args) {
//通过构建器得到Clothes实例
Clothes clo = new Clothes.Builder("T恤", 32).Color("red").Price(99.99).build();
}
}
第三条:用私有构造器或者枚举类型强化Singleton属性
package createOrdestoryObject;
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis(){}
public static Elvis getInstance (){
return INSTANCE;
}
}
第四条:通过私有构造器强化不可实例化的能力
若企图将类变得不可实例化,可以是有私有构造器。参照上一个示例。
第五条:避免创建不必要的对象
public static void main(String[] args) {
System.out.println(LocalTime.now());
//错误的将long写为Long,这样会创建多个Long对象
Long sum = 0L;
for(long i =0 ;i<Integer.MAX_VALUE;i++){
sum +=i;
}
System.out.println(sum);
System.out.println(LocalTime.now());
}
在这个例子中错误的使用Long这个对象,在我的机器上用Long计算用了22秒,而用long计算用了4秒,所以我们应尽量使用基本类型而不是装箱类型。
第六条:消除过期的对象引用
java的垃圾回收机制是利用根不可达来进行无用对象的回收的,若是一直有无用的引用引用着这个对象的话,这个对象是不会被垃圾回收器回收的。若是这样的无用对象越来越多的话,就会造成内存的泄露。
请看下面这个例子:
public class Stack {
private Object [] elements;
private int size = 0;
private final static int DEFAULT_INITIAL_CAPACITY = 16;
public Stack(){
elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(Object e){
ensureCapacity();
elements[size++] = e;
}
public Object pop(){
if(size == 0){
throw new EmptyStackException();
}
Object obj = elements[--size];
//此段代码必须有,否则数组中会一直保留着对这个对象的无效引用,直至该数组元素被覆盖。
elements[size] = null;
return obj;
}
public void ensureCapacity(){
if(elements.length == size){
elements = Arrays.copyOf(elements, 2*size+1);
}
}
}
注意:elements[size] = null;
此段代码必须有,否则数组中会一直保留着对这个对象的无效引用,直至该数组元素被覆盖。
第七条:避免使用终结方法
java中不仅不保证终结方法会被及时的执行,而且根本不保证它们会被执行,尽量使用显示的终结方法,如InputStream、OutputStream等类的close方法。