使用静态工厂方法的优点:java
具备多个构造器的类用户每每不知道该用哪一个,可考虑提供多个合适命名的静态工厂方法。缓存
不可变类能够预先建立好实例,或者将构件好的实例缓存起来,从而避免重复建立对象。此方法相似于Flyweight模式。若是程序常常请求建立相同的对象,而且建立对象的代价很高,此项技术能够极大地提高性能。框架
在选择返回对象的类时就有了更大的灵活性。好比:API能够提供对象,可是该对象实际的类能够被隐藏起来,用户无需知道其具体类型。静态工厂方法返回的对象所属的类,在编写包含该静态工厂方法的类时能够没必要存在。这种灵活的静态工厂方法构成了服务提供者框架的基础。ide
简单例子:性能
1 public interface Service { 2 // service-specific methods go here 3 }
public interface Provider { public Service newService(); }
1 import java.util.Map; 2 import java.util.concurrent.ConcurrentHashMap; 3 4 /** 5 * Noninstantiable class for service registration and access 6 */ 7 public class Services { 8 private Services(){} //prevent instantiation 9 10 private static final Map<String, Provider> providers = new ConcurrentHashMap<>(); 11 private static final String DEFAULT_PROVIDER_NAME = "<def>"; 12 13 public static void registerDefaultProvider(Provider p) { 14 registerProvider(DEFAULT_PROVIDER_NAME, p); 15 } 16 17 public static void registerProvider(String name, Provider p) { 18 providers.put(name, p); 19 } 20 21 // Service access API 22 public static Service newInstance() { 23 return newInstance(DEFAULT_PROVIDER_NAME); 24 } 25 26 public static Service newInstance(String name) { 27 Provider p = providers.get(name); 28 29 if (null == p) { 30 throw new IllegalArgumentException("No provider registered with name: " + name); 31 } 32 33 return p.newService(); 34 } 35 36 }
在建立参数化类型实例时,使代码变得简洁spa
缺点:code
主要缺点:类若是不含有公有的或者受保护的构造器,就不能被子类化。对象
第二个缺点在于,与其余静态方法实际上没有任何区别blog
没有像构造器那样在API文档中明确标识出来,所以,对于一个提供了静态方法而不是构造器的类来讲,要想查明如何实例化一个类,是很是困难的。你能够在类或者接口注释中关注静态工厂,并遵照标准命名习惯,来弥补这一劣势。接口
静态工厂方法的惯用名称:
不太严格的讲,该方法返回的实例与参数具备相同的值,这样的静态工厂方法其实是类型转换方法。
valueOf的一种更简洁的替代,在EnumSet中使用并流行起来
返回的实例是经过方法的参数来描述的,可是不可以说与参数具备相同的值。
像getInstance同样,可是newInstance可以确保返回的每一个实例都与全部其余实例不一样
想getInstance同样,可是在工厂方法处于不一样的类中的时候使用。Type表示工厂方法返回的对象类型
像newInstance同样,可是在工厂方法处于不一样的类中时候使用。
简而言之,静态工厂方法和构造器都各有用处,须要理解各自的长处。静态工厂一般更加合适,切忌第一反应就是提供公有的构造器,而不先考虑静态工厂方法。