在创建对象是,静态工厂的优势有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);