Item 1: Consider static factory methods instead of constructors
public class Child {
int age = 10;
int weight = 30;
public static Child newChild(int age, int weight){
Child child = new Child();
child.age = age;
child.weight = weight;
return child;
}
public static Child newChildWithWeight(int weight){
Child child = new Child();
child.weight = weight;
return child;
}
public static Child newChildWithAge(int age){
Child child = new Child();
child.age = age;
return child;
}
public static void main(String[] args) {
//Child child = new Child();
Child childwithweight = Child.newChildWithWeight(20);
Child childwithage = Child.newChildWithAge(40);
System.out.println(childwithweight.weight);
System.out.println(childwithage.age);
}
}
Item 2: Consider a builder when faced with many constructor parameters
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;//份
//必要参数
public Builder(int servingSize,int servings){
this.servingSize=servingSize;
this.servings=servings;
}
private int calories = 0;
private int fat = 0;
private int sodium = 0;
private int carbohydrate = 0;
public Builder calories(int val){
calories = val;
return this;
}
public Builder fat(int val){
fat = val;
return this;
}
public Builder sodium(int val){
sodium = val;
return this;
}
public Builder carbohydrate(int val){
carbohydrate = val;
return this;
}
public NutritionFacts build(){
return new NutritionFacts(this);
}
}
private NutritionFacts(Builder builder){
servingSize = builder.servingSize;
servings = builder.servings;
calories = builder.calories;
fat = builder.fat;
sodium = builder.sodium;
carbohydrate = builder.carbohydrate;
}
}
- 对于NutritionFacts来说,包含了三部分,final成员变量,私有构造器、静态内部类。final成员变量保证了初始化安全性,即在构造器执行完成之前必须显示对成员变量初始化。这里是在构造函数中传入Builder来对其初始化。
- 构造器为什么要声明为私有的?保证了外部创建实例时只能通过静态内部类的build()方法来实现。
- 为什么是静态内部类?因为构造器是私有的,导致外部只能通过内部类的build()方法来实现。而非静态内部类对象的创建又依赖于外部类对象,即必须有外部类对象来创建(外部类对象.new InnerClassName()),这样就陷入了死循环。而静态内部类不需要依赖于外部类对象,只需要通过 “new OutClassName.InnerClassName()”就可以完成实例化。
- 内部类Builder通过final关键字来区分必需参数和非必需参数。通过builder()方法完成外部类实例化。这里利用内部类可以访问外部私有元素的特性。
- 总的来看,就是外部类通过静态内部类完成了自己成员变量的初始化。
使用时候,比较简单与清晰:NutritionFacts cocoCola = new NutritionFacts.Builder(20,15).calories(11).carbohydrate(12).build();
**
外部类名.this 的理解:
当在一个类的内部类中,如果需要访问外部类的方法或者成员域的时候,如果使用 this.成员域(与 内部类.this.成员域 没有分别) 调用的是内部类的域 , 如果我们想要在内部类中访问外部类的成员域的时候,就要必须使用 外部类.this.成员域。使用类名.this更能显示出关联性。*在该代码块中使用return this可以实现链式调用。
*关于内部类的理解
在一个类的内部又定义了一个类,这个类就称之为内部类(Inner Class)
语雀内容