Effective Java

31 阅读2分钟

chapter2 创建和销毁对象

何时以及如何创建对象,何时以及如何避免创建对象,如何确保它们能够适时的销毁,以及如何管理对象销毁之前必须进行的各种清理动作。

2.1 用静态工厂方法代替构造器

public static Boolean valueOf(boolean b) {
	return b ? Boolean.TRUE : Boolean.FALSE;
}

缺点:仅提供静态工厂方法的主要局限是,没有公共或受保护构造函数的类不能被子类化。

2.2 当构造函数有多个参数时,考虑改用构建器

重载构造器。

JavaBeans模式。

// JavaBeans Pattern - allows inconsistency, mandates mutability
public class NutritionFacts {
    // Parameters initialized to default values (if any)
    private int servingSize = -1; // Required; no default value
    private int servings = -1; // Required; no default value
    private int calories = 0;
    private int fat = 0;
    private int sodium = 0;
    private int carbohydrate = 0;
    public NutritionFacts() { }
    // Setters
    public void setServingSize(int val) { servingSize = val; }
    public void setServings(int val) { servings = val; }
    public void setCalories(int val) { calories = val; }
    public void setFat(int val) { fat = val; }
    public void setSodium(int val) { sodium = val; }
    public void setCarbohydrate(int val) { carbohydrate = val; }
}

建造者模式。

// Builder Pattern
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 {
        // Required parameters
        private final int servingSize;
        private final int servings;
        // Optional parameters - initialized to default values
        private int calories = 0;
        private int fat = 0;
        private int sodium = 0;
        private int carbohydrate = 0;

        public Builder(int servingSize, int servings) {
            this.servingSize = servingSize;
            this.servings = servings;
        }

        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;
    }
}

// 所有参数默认值都在一个位置。构建器的 setter 方法返回构建器本身,这样就可以链式调用,从而得到一个流畅的 API
NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8)
.calories(100).sodium(35).carbohydrate(27).build();

对于所有对象都通用的方法

类和接口

泛型

枚举和注解

Lambda和Stream

方法

50. 如果一个类包含有从客户端得到或返回到客户端的可变组件,这个类就必须保护性的拷贝这些组件。

通用编程

59. ThreadLocalRandom。

异常

并发

序列化