Item1: 考虑使用静态工厂方法代替构造方法

1 什么是静态工厂方法

静态工厂方法不是指设计模式中的工厂方法,而是在类中提供一个静态方法,该类方法返回类的一个实例。
在Java API中有许多这样的例子,如所有的基本对象的包装类都会提供一个valueOf()的方法用于获取该对象的实例:

String str = String.valueOf(1);
Integer integer = Integer.valueOf("1");
Long lon = Long.valueOf("1");
Double dou = Double.valueOf("1");

2 静态工厂方法的好处

2.1 静态工厂方法可以有名字,而构造方法无法命名

编程中起名字很重要,不管是变量名还是方法名,最好能让人见名知意,易于阅读。比如BigInteger.probablePrime方法,返回一个可能为素数的BigInteger。
在当需要提供多个构造方法,而构造方法之间可能仅仅是参数顺序不一样,这样很容易引发错误。而静态工厂方法完全可以避免这种问题

2.2 静态工厂方法不一定要创建一个新对象

这一点在单例模式中有很好的体现。通过将构造方法私有,再提供一个静态方法每次返回同一个实例。
还有一种常见的情况,如果对象的创建成本很高,为了提高效率,不会每次都创建一个新对象,而是使用对象池,将用完的对象放入该池中,当需要一个对象时,通过静态工厂方法返回,方法内部判断对象池中是否有空闲对象,如果没有再创建新对象。

2.3 静态工厂方法可以返回其返回类型的任何子类

首先来看例子:

List<Object> emptyList = Collections.emptyList();

源码:

public static final List EMPTY_LIST = new EmptyList<>();
public static final <T> List<T> emptyList() {
    return (List<T>) EMPTY_LIST;
}
private static class EmptyList<E>
        extends AbstractList<E>
        implements RandomAccess, Serializable {
        private static final long serialVersionUID = 8842843931221139166L;

        public Iterator<E> iterator() {
            return emptyIterator();
        }
        public ListIterator<E> listIterator() {
            return emptyListIterator();
        }

        public int size() {return 0;}
        public boolean isEmpty() {return true;}

        public boolean contains(Object obj) {return false;}
        public boolean containsAll(Collection<?> c) { return c.isEmpty(); }
        public int hashCode() { return 1; }
}

在源码中可以看到,该方法返回的是一个常量,而该常量是通过创建一个EmptyList对象,它是List的一个子类。
一般而言,对于一个接口Type(如这里的Collection),会提个一个Types的类(如这里的Collections),该类会提供私有构造方法,通过静态工厂方法放回示例,而其中大部分的类都对外隐藏,如上面看到的EmptyList类别设置为private。这样会使整个API更为紧凑。且当下次我要修改EmptyList的实现时,对使用者没有影响。

2.4 返回对象的类可以根据输入参数的不同而不同

2.5 返回对象的类不需要存在

3 缺点

  • 当构造方法被私有时,无法被继承(这个点倒是没有很理解,不私有构造方法就可以解决这个问题)
  • 程序员无法找到静态工厂方法。主要是指java doc不会把静态公共方法和构造方法放在一起,二是将其和其他普通方法放在一起

4 静态工厂方法常用的名字

  • from
  • of
  • valueOf
  • instance/getInstance
  • create/newInstance
  • getXxxx
  • newXxxx

你可能感兴趣的:(effective,java)