文章来源:Effective Java第二章
常规构造的方式有两种:构造器structure和静态工厂static factory method;静态工厂相比构造器有以下几点优势:
1.静态工厂有名称:具有适当名称的静态工厂更容易调用,也更容易阅读。
//构造器返回素数
BigInteger(int,int,Random)
//静态工厂返回素数
BigInteger.probablePrime
2.不必每次调用它们的时候都创建一个新的对象,能够预先创建好对象,进行重复利用,每次返回相同的对象,减少系统开销。
3.可以返回原返回类型的任何子类型的对象。
EnumSet没有公有构造器,只有公有构造方法。当元素<=64,返回RegalarEnumSet实例,反之,返回JumboEnumSet实例。
在参数列表很多的时候,使用两种方式都会有一定的麻烦。用不同的参数进行构造就需要更多的构造方法或者更多的静态工厂方法。这个时候就考虑使用构建器Builder。
既能保证安全性也能保证可读性。不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器,得到一个builder对象,然后在builder对象上调用类似于setter的方法,来设置每个相关的可选参数。最后调用无参的build方法来生成不可变的对象。
实现代码如下:
/**
* Created by KingBoy on 2016/9/28.
*/
public class NutritionFacts {
private final int servingSize;
private final int servings;
private final int calories;
private final int fat;
private final int sodium;
private final int carbohydrate;
public static class Builder{
//需要的参数
private final int servingSize;
private final int servings;
//可选参数
private int calories =0;
private int fat=0;
private int sodium=0;
private int carbohydrate=0;
public Builder(int servingSize,int servings){
this.servings=servings;
this.servingSize=servingSize;
}
<span style="white-space:pre"> </span>//返回Builder方便链式调用
public Builder calories(int val){
this.calories=val;
return this;
}
public Builder fat(int val){
this.fat=val;
return this;
}
public Builder sodium(int val){
this.sodium=val;
return this;
}
public Builder carbohydrate(int val){
this.carbohydrate=val;
return this;
}
public NutritionFacts build(){
return new NutritionFacts(this);
}
}
private NutritionFacts(Builder builder){
servings=builder.servings;
servingSize=builder.servingSize;
calories=builder.calories;
fat=builder.fat;
sodium=builder.sodium;
carbohydrate=builder.carbohydrate;
}
}
调用方式:
public static void main(String[] args) {
NutritionFacts nutritionFacts=new NutritionFacts.Builder(100,200).calories(50).fat(100).sodium(85).carbohydrate(65).build();
}