一、考虑使用静态工厂方法代替构造器
1、它有名称
2、不必在每次调用它们的时候都创建一个新对象(单例模式)
3、可以返回原返回类型的任何子类型对象。(参见java.util.Collections)
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
public Boolean(boolean value) {
this.value = value;
}
在JDK中就提供了使用静态工厂方法的方式来替代构造器。
对于Collecions就是使用静态工厂方法来获取它内部实现的一些类对象,返回对象的类都是非共有的,这样就可以减少API数量的。
4、静态工厂通常更加适合,因此切记第一反应就是提供公有的构造器,而不先考虑静态工厂。
二、当遇到多个构造器参数时要考虑用构造器
1、重叠构造器
package jdk.math;
/**
* Created by yesh on 2015/4/5.
*/
public class NutritionFacts {
private float weight;
private float factWeight;
private float servings;
public NutritionFacts(float weight){
this(weight,0);
}
public NutritionFacts(float weight,float factWeight){
this(weight,factWeight,0);
}
public NutritionFacts(float weight,float factWeight,float servings){
this.weight = weight;
this.factWeight = factWeight;
this.servings = servings;
}
}
2、可以使用JavaBean的方式,来作为一个参数
JavaBean方式,因为构造过程中被分到了几个调用中,在构造过程中就可能处于不一致的状态,在线程中处于不安全的状态。
3、使用建造者模式(使用该模式后,在创建的时候是可以写入的,一旦创建成功后该对象就是不可变的,也就是可以保证线程的安全行)
package jdk.math;
/**
* Created by yesh on 2015/4/5.
*/
public class NutritionFacts {
private float weight;
private float factWeight;
private float servings;
public static class Builder{
private float weight;
private float factWeight;
private float servings;
public Builder(){
}
public Builder weight(float weight){
this.weight = weight;
return this;
}
public Builder factWeight(float factWeight){
this.factWeight = factWeight;
return this;
}
public Builder servings(float servings){
this.servings = servings;
return this;
}
public NutritionFacts build(){
return new NutritionFacts(this);
}
}
public NutritionFacts(Builder builder){
this.weight = builder.weight;
this.factWeight = builder.factWeight;
this.servings = builder.servings;
}
public static void main(String[] args) {
NutritionFacts.Builder builder = new NutritionFacts.Builder();
NutritionFacts nutritionFacts = builder.servings(12).
weight(12).factWeight(12).build();
}
}
查看protobuf中生成的对象也是使用了该方式来做的, rotobuf使用protoc生成的java类, 这个类一旦创建了对象,该对象就是只读的,不能修改它的任何属性,也就是说这个类是只读类。
三、使用枚举方式来创建单例模式
package jdk.math;
/**
* 使用枚举方式来实现单例模式
*/
public enum SingleEnum {
himself;
private String serving = "yezi";
public String getServing() {
return serving;
}
}
SingleEnum singleEnum = SingleEnum.himself;
System.out.println(singleEnum.getServing());
四、不能依赖终结方法来更新持久状态
1、例如对数据库的连接,试图使用conn = null来释放数据库的连接是不能达到的。
2、不要试图使用终结方法来释放锁。
3、System.gc()和System.runFinalization()不能保证终结方法一定执行。