Item 1: Consider static factory methods instead of constructors

  1. public class Child {
  2. int age = 10;
  3. int weight = 30;
  4. public static Child newChild(int age, int weight){
  5. Child child = new Child();
  6. child.age = age;
  7. child.weight = weight;
  8. return child;
  9. }
  10. public static Child newChildWithWeight(int weight){
  11. Child child = new Child();
  12. child.weight = weight;
  13. return child;
  14. }
  15. public static Child newChildWithAge(int age){
  16. Child child = new Child();
  17. child.age = age;
  18. return child;
  19. }
  20. public static void main(String[] args) {
  21. //Child child = new Child();
  22. Child childwithweight = Child.newChildWithWeight(20);
  23. Child childwithage = Child.newChildWithAge(40);
  24. System.out.println(childwithweight.weight);
  25. System.out.println(childwithage.age);
  26. }
  27. }

Item 2: Consider a builder when faced with many constructor parameters

  1. public class NutritionFacts {
  2. private final int servingSize;//份容量
  3. private final int servings;//份
  4. private final int calories;//卡路里
  5. private final int fat;//脂肪
  6. private final int sodium;//钠
  7. private final int carbohydrate;//糖类
  8. public static class Builder{
  9. private final int servingSize;//份容量
  10. private final int servings;//份
  11. //必要参数
  12. public Builder(int servingSize,int servings){
  13. this.servingSize=servingSize;
  14. this.servings=servings;
  15. }
  16. private int calories = 0;
  17. private int fat = 0;
  18. private int sodium = 0;
  19. private int carbohydrate = 0;
  20. public Builder calories(int val){
  21. calories = val;
  22. return this;
  23. }
  24. public Builder fat(int val){
  25. fat = val;
  26. return this;
  27. }
  28. public Builder sodium(int val){
  29. sodium = val;
  30. return this;
  31. }
  32. public Builder carbohydrate(int val){
  33. carbohydrate = val;
  34. return this;
  35. }
  36. public NutritionFacts build(){
  37. return new NutritionFacts(this);
  38. }
  39. }
  40. private NutritionFacts(Builder builder){
  41. servingSize = builder.servingSize;
  42. servings = builder.servings;
  43. calories = builder.calories;
  44. fat = builder.fat;
  45. sodium = builder.sodium;
  46. carbohydrate = builder.carbohydrate;
  47. }
  48. }
  1. 对于NutritionFacts来说,包含了三部分,final成员变量,私有构造器、静态内部类。final成员变量保证了初始化安全性,即在构造器执行完成之前必须显示对成员变量初始化。这里是在构造函数中传入Builder来对其初始化。
  2. 构造器为什么要声明为私有的?保证了外部创建实例时只能通过静态内部类的build()方法来实现。
  3. 为什么是静态内部类?因为构造器是私有的,导致外部只能通过内部类的build()方法来实现。而非静态内部类对象的创建又依赖于外部类对象,即必须有外部类对象来创建(外部类对象.new InnerClassName()),这样就陷入了死循环。而静态内部类不需要依赖于外部类对象,只需要通过 “new OutClassName.InnerClassName()”就可以完成实例化。
  4. 内部类Builder通过final关键字来区分必需参数和非必需参数。通过builder()方法完成外部类实例化。这里利用内部类可以访问外部私有元素的特性。
  5. 总的来看,就是外部类通过静态内部类完成了自己成员变量的初始化。

使用时候,比较简单与清晰:
NutritionFacts cocoCola = new NutritionFacts.Builder(20,15).calories(11).carbohydrate(12).build();
**

外部类名.this 的理解:
当在一个类的内部类中,如果需要访问外部类的方法或者成员域的时候,如果使用 this.成员域(与 内部类.this.成员域 没有分别) 调用的是内部类的域 , 如果我们想要在内部类中访问外部类的成员域的时候,就要必须使用 外部类.this.成员域。使用类名.this更能显示出关联性。*在该代码块中使用return this可以实现链式调用。

*关于内部类的理解
在一个类的内部又定义了一个类,这个类就称之为内部类(Inner Class)
语雀内容