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属性

四、通过私有构造器强化不可实例化的能力

五、避免创建不必要的对象

六、消除过期的对象引用

七、避免使用终结方法

展开阅读全文

没有更多推荐了,返回首页