使用靜態工廠方法的優點: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同樣,可是在工廠方法處於不一樣的類中時候使用。
簡而言之,靜態工廠方法和構造器都各有用處,須要理解各自的長處。靜態工廠一般更加合適,切忌第一反應就是提供公有的構造器,而不先考慮靜態工廠方法。