Effective Java

94 阅读2分钟

创建和销毁对象

第1条:用静态工厂方法代替构造器

创建一个类的实例的方法

方法1:公有的构造方法

方法2:静态工厂方法(static factory method)

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

静态工厂方法的优点

1. 有名称: 静态工厂方法有名称,可以更清楚的知道创建的对象是什么样的;而构造方法,只能通过重载,更换顺序或类型来提供不同的构造器,但是如果没有详细的文档,依然不会清楚哪个构造器是创建什么样类型的对象。

2. 不必每次调用他们的时候都创建一个新对象: 可以使用之前创建好的实例,或者将构建好的实例缓存起来,重复利用。例如 Boolean.valueOf(boolean);避免创建重复的对象。

3.可以返回原返回类型的任何子类型的对象: 在选择返回值类型的时候就有了更大的灵活性,API可以返回对象,对象的类也不会变成公有的。

// 可以返回对象的API
public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K, ? extends V> m) {
    return new UnmodifiableMap<>(m);
}

// 私有的类
private static class UnmodifiableMap<K,V> implements Map<K,V>, Serializable {
    private static final long serialVersionUID = -1034234728574286014L;

    private final Map<? extends K, ? extends V> m;

    UnmodifiableMap(Map<? extends K, ? extends V> m) {
        if (m==null)
            throw new NullPointerException();
        this.m = m;
    }
}

4.所有的对象的类可以随着每次调用而发生变化,这取决于静态工厂方法的参数值: 返回对象的类也可能随着发行版本的不同而不同。

public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
    Enum<?>[] universe = getUniverse(elementType);
    if (universe == null)
        throw new ClassCastException(elementType + " not an enum");

    if (universe.length <= 64)
        return new RegularEnumSet<>(elementType, universe);
    else
        return new JumboEnumSet<>(elementType, universe);
}

当枚举元素个数小于等于64,创建一个RegularEnumSet对象,大于64,创建一个