Effective Java 第2章: 創建和銷燬對象

一、用靜態工廠方法代替構造器

靜態工廠方法與構造器相比有以下幾個優點:

  • 靜態工廠方法有名稱;
  • 不必每次調用的時候都創建新的對象;
  • 可以返回原返回類型的任何子類型的對象;
  • 在創建參數化類型實例的時候沒,靜態工廠方法使得代碼變得更加簡潔;
缺點:
  • 類如果不含有公有的或者受保護的構造器,就不能被子類化;
  • 靜態工廠方法與其他的靜態方法實際上並沒有任何區別;
靜態工廠方法常用的名稱:
  • valueOf:一般用作類型轉換方法;
  • of:valueOf更簡潔的代替,在EnumSet中使用病流行起來;
  • getInstance:用於返回實例;
  • newInstance:返回的實例與其他的所有實例都不同;
  • getType:和newInstance類似;
代碼:https://github.com/yanzxu/EffectiveJava/tree/master/src/main/java/chapter1/staticfactory
public class Services {
    private Services() {
    }

    private static final Map<String, Provider> providers = new ConcurrentHashMap<>();

    private static final String DEFAULT_PROVIDER_NAME = "test";

    public static void registerDefaultProvider(Provider provider) {
        registerProvider(DEFAULT_PROVIDER_NAME, provider);
    }

    public static void registerProvider(String name, Provider prodiver) {
        providers.put(name,prodiver);
    }

    public static Service newInstance() {
        return newInstance(DEFAULT_PROVIDER_NAME);

    }

    public static Service newInstance(String name){
        Provider p = providers.get(name);

        if (p == null) throw new IllegalArgumentException("No provider registered with name: " + name);

        return p.newService();
    }
}

二、遇到多個構造器參數時考慮用構造器Builder模式

情景

對於多參構造器,其中一些參數是必須的而另一些則是可選的,這樣的話我們在創建類的時候就要創建多個含有不同參數的構造器,不僅笨重而且不易區分不同的構造器,針對這種情況我們就可以採用Builder模式來替代多參構造器,如下所示。

代碼 https://github.com/yanzxu/EffectiveJava/tree/master/src/main/java/chapter1/builder

public class Person {

    private String name;
    private boolean gender;
    private int age;
    private String address;
    private Date birthday;

    private Person(Builder builder){
        this.name = builder.name;
        this.gender = builder.gender;
        this.age = builder.age;
        this.address = builder.address;
        this.birthday= builder.birthday;
    }


    public static class Builder {
        // required parameters
        private String name;
        private boolean gender;

        // optional parameters: initialized to default values
        private int age = 0;
        private String address = "China";
        private Date birthday = new Date();

        public Builder(String name, boolean gender) {
            this.name = name;
            this.gender = gender;
        }

        public Builder age(int age) {
            this.age= age;
            return this;
        }

        public Builder address(String address) {
            this.address= address;
            return this;
        }

        public Builder birthday(Date birthday) {
            this.birthday= birthday;
            return this;
        }

        public Person build() {
            return new Person(this);
        }
    }
}
創建對象

此時創建對象只需要傳入必選參數就可以了。

new Person.Builder("Eric", true)
                .age(22)
                .address("Beijing")
                .build();

三、通過私有構造器或者枚舉類型強化Singleton屬性

四、通過私有構造器強化不可實例化的能力

五、避免創建不必要的對象

六、消除過期的對象引用

七、避免使用終結方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章