在創建對象是,靜態工廠的優勢有4個:
1.有名字
probablePrime表示可能的素數
BigInteger bigInteger = BigInteger.probablePrime(3, new Random());
同樣的功能,使用構造器就差了可讀性
BigInteger bigInteger = new BigInteger(3, 100, new Random());
2.不一定要創建新對象
Boolean b = Boolean.valueOf(false);
3.可以返回子類
Collections可以返回各種對象,他們都指向接口。他們具體實現都在Collections內部。這樣他們不需要暴露個用戶,擁有極高的靈活性。
下面是Collections 裏的一個靜態工廠和包私有類
public static <K,V> NavigableMap<K,V> checkedNavigableMap(NavigableMap<K, V> m,
Class<K> keyType,
Class<V> valueType) {
return new CheckedNavigableMap<>(m, keyType, valueType);
}
static class CheckedNavigableMap<K,V> extends CheckedSortedMap<K,V>
implements NavigableMap<K,V>, Serializable
4.靜態工廠方法構造對象,可以根據參數變換。OpenJDK中,
EnumSet只有一個靜態工廠(of)做構造器。這個靜態工廠返回兩個子類的對象,RegularEnumset和JumboEnumset。如果參數個數小於等於64便返回RegularEnumset,大於64則返回JumboEnumset。
public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> 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);
}
5.靜態工廠返回的對象,這個對象對應的類可以事先不存在。
Connection //service interface
DriverManager.registerDriver(driverImpl); //driver registration api
DriverManager.getConnection(); //service access api
Driver //Driver interface
用於構造對象,靜態工廠較構造器的劣勢
劣勢1.不能繼承。在Collections裏面,包私有類的實現是沒法被繼承的
static class UnmodifiableCollection<E> implements Collection<E>, Serializable {
private static final long serialVersionUID = 1820017752578914078L;
final Collection<? extends E> c;
。。。 。。。
劣勢2.工廠方法在文檔中沒有專門的標識,不過有些約定俗稱的寫法。
form-類型轉換的工廠
Date instant = Date.from(Instant.now());
of-聚合類工廠
EnumSet enumSet = EnumSet.of(one, two, three);
valueOf-類型轉換工廠
Integer integer = Integer.valueOf(Integer.MAX_VALUE);
instance 或者getInstance-返回對象,不一定是同一個對象
Calendar c = Calendar.getInstance();
create和newInstance,創建對象,並且保證是新建的對象
Object strArray = Array.newInstance(String.class, 10);
getType-如果返回的對象不是所在類的對象,用getType()
FileStore fileStore = Files.getFileStore(path);
newType
BufferedReader br = Files.newBufferedReader(path);
type
List<Complaint> litany = Collections.list(legacyLitany);