Java学习笔记系列

Effective Java Item 2 - 构造器

2018-02-05  本文已影响0人  SonyaBaby

在刚接触C++和Java时候,都会先学到构造器,用的多就习惯了重叠式构造器方式,但是当参数很多的时候就会diss存值的顺序,推荐使用builder,下面还是用书中的例子作说明

public class Item2_Builder {

  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{ //类内部构造器
    // required
    private final int servingSize;
    private final int servings;
    // optional
    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;
    }
    public Builder fat(int val){//可选填的参数
      this.fat = fat;
      return this;
    }
    public Builder sodium(int val){//可选填的参数
      this.sodium = sodium;
      return this;
    }
    public Builder calories(int val){//可选填的参数
      this.calories = calories;
      return this;
    }
    public Builder carbohydrate(int val){//可选填的参数
      this.carbohydrate = carbohydrate;
      return this;
    }

    public Item2_Builder build(){//将Builder的值[复制]给Item2_Builder
      return new Item2_Builder(this);
    }
  }

  private Item2_Builder(Builder builder){//将Builder的值[复制]给Item2_Builder
    calories = builder.calories;
    servingSize = builder.servingSize;
    servings = builder.servings;
    fat = builder.fat;
    sodium = builder.sodium;
    carbohydrate = builder.carbohydrate;
  }

我们在调用时候可以这样使用

public static void main(String[] args) {
  Item2_Builder cocaCola = new Item2_Builder.Builder(100,10).calories(100).fat(50).sodium(60)
.build();
  }
}

Builder相对于setter方式,好处自然也很明显啦,不需要重复的写A.set,可以串成链式。

A.set(B);
A.set(C);
A.set(D);
A.set(E);

Builder模式模拟了具名的可选参数,就像Ada和Python中的一样。

builder可以对多参数加约束条件:

Builder相比构造器的优点:

Builder 不足之处

抽象工厂Builder<T>

public interface Builder<T>{
    public T builder();
 }

eg:
Item2_Builder.Builder()类可以实现Builder<Item2_Builder>

注意:
传统的抽象工厂实现的是Class对象,用newInstance来充当build会隐藏一些问题:
newInstance总是企图调用类的无参构造器,这个构造器可能根部不存在,如果类没有可以访问的无参构造器,编译时也不会报错。在运行时将会报错:InstantiationException或者IllegalAccessException
即newInstance缺乏响应的throws子句,换句话说Class.newInstance破坏了编译时的异常检查。Builder接口弥补了这些。

上一篇下一篇

猜你喜欢

热点阅读