创建一个对象的传统方式就是使用构造器。还有一种方式就是使用静态工厂方法。静态工厂方法返回类的实例。以下是Boolean 对象的一个valueOf方法
public static Boolean valueOf(boolean b) { return (b ? TRUE : FALSE); }
本条目的静态工厂方法并不等同于设计模式中的工厂模式。
静态工厂方法相对于构造器来说,既有优势,也有劣势。
静态工厂方法的第一个优势就是它有名字,这里有名字指得是,我们可以自定义名字,从而增加代码的可读性。我们起名也要增加代码的可读性,让人一眼能看出方法名的含义。
静态工厂方法的第二个优势是不必每次执行都创建新的对象,使用预先构建好的实例,或者将之前构建的实例缓存起来,减少创建对象的开销,提升程序性能。
第三个优势是它可以返回原类型的任何子类型,这使得我们可以更加自由的选择返回类型,隐藏实现类使得API 变得更加简洁。
第四个优势是返回的对象可以随着每次调用发生变化,这取决于静态工厂方法的参数值
EnumSet 就是一个很好的示例。 EnumSet 没有公有的构造器,只有静态工厂方法。 如果它的元素有 64个或者更少,就像大多数枚举类型一样,静态工厂方法就会返回一个 RegalarEumSet 实例,用单个 long 进行支持;如果枚举类型有 65 个或者更多元素,工厂就返回 JumboEnumSet实例,用一个 long 数组进行支持。
public static <E extends Enum> EnumSet noneOf(Class 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); }
这两个实现类的存在对于客户端来说是不可见的 如果 RegularEnumSet 不能再给小的枚举类型提供性能优势,就可能从未来的发行版本中将它删除,不会造成任何负面的影响。同样地,如果事实证明对性能有好处,也可能在未来的发行版本中添加第 三甚 至第四个EnumSet 实现 客户端永远不知道也不关心它们从工厂方法中得到的对象的类,它们只关心它是 EnumSet 的某个子类。
第五个优势是静态工厂返回的某个类的对象,在编写该静态方法时可以不存在** 最好的例子就是像JDBC 这种的服务提供者框架API, 服务提供者框架是指这样一个系统:多个服务提 供者实现一个服务,系统为服务提供者的客户端提供多个实 现,并把它们从 多个实现 中解耦出来。
静态工厂的主要缺点之一是如果类不含有公有或者受保护的构造器,就不能被子类化,但是这样会鼓励程序员们使用复合来代替继承。
第二个缺点是静态方法不便于查找,程序员查找一个实例化的方法可能不像找构造器那么复杂。 通过在类或者接 注释,关注静态工厂并遵守标准 的命 习惯,也可以弥补这 劣势。