创建一个类的实例的方法,最常用的是提供一个公有[public]的构造器,另外还有一种方法是类可以提供一个公有的静态工厂方法。
静态工厂方法对于构造器有着不同的优势和劣势。
优势:
1.静态工厂方法可定义更有意思的名称,而构造函数只能是类名。
eg:BigInteger的构造函数返回的可能是素数,不过使用BigInteger.probablePrime更加明确。
2.静态工厂方法不必没有调用的时候都创建一个新的对象,这对于不可变类可以预先构造好实例,调用时静态工厂方法直接返回即可。
eg:Boolean.valueOf方法。类似Flyweight模式,参考枚举类型。
3.静态工厂方法可以返回原返回类型的任何子类型的对象,适用于基于接口的框架。
eg:Java的集合框架。EnumSet。服务提供者框架,比如JDBC,包括三个重要的组件接口(Service Interface),提供者实现的;提供者注册API(Provider Registration API),这是系统用了注册实现的,让客户端可以使用他们;服务访问API(Service Access API),是客户端用来获取服务实例的的,是灵活的静态工厂方法。还有第四个组件服务提供接口(Service Provider Interface),提供者用来负责创造其服务实现的实例的,如果没有服务提供者接口,那实现只能按照类名注册,并通过反射进行实例化。
4.静态方法在创建参数化类型的实例的时候,可以使得代码更加简洁。利用了类型推导。
劣势:
1.类如果不包括公有的或者受保护的构造器,就不能子类化。
对应优势3。
2.静态工厂方法实际与静态方法没有任何区别,因此不能从方法名上知道是在构造类型。
因此有了静态工厂方法的一些惯用名称:
- valueOf 该方法返回的实例与参数具有相同的值,实际是类型转换方法。
- of valueOf的一种替代,EnumSet。
- getInstance Singleton单例模式,返回唯一的实例。
- newInstance 返回的实例是一个新的实例,与之前返回的都不相同。
- getType 与getInstance一样,但是在工厂方法处于不同的类时候使用。
- newType