注意:这里的静态工厂方法要注意和设计模式的静态工厂方法区分开来,没有联系。
静态工厂方法和构造函数都是用来创建对象的。
一、优缺点
1.1 静态工厂相对于构造函数的第一大优点是有名称
适合场景:当一个类需要多个带有相同签名的构造函数时,推荐使用静态工厂方法
替换构造函数。
静态工厂方法代替构造器在jdk中的运用一:UUID类nameUUIDFromBytes、
//私有构造函数,用一个byte数组来创建一个UUID
private UUID(byte[] data) {
//do stuff
}
public UUID(long mostSigBits, long leastSigBits) {
this.mostSigBits = mostSigBits;
this.leastSigBits = leastSigBits;
}
//静态工厂方法,用一个byte数组类返回版本为3的UUID
public static UUID nameUUIDFromBytes(byte[] name) {
//do stuff
return new UUID(md5Bytes);
}
//静态工厂方法,返回版本为4的UUID
public static UUID randomUUID() {
//do stuff
return new UUID(randomBytes);
}
nameUUIDFromBytes与私有构造函数签名一样,此时采用静态工厂方法:nameUUIDFromBytes
代替构造函数。
1.2 静态工厂方法不必每次都创建新对象
对于不可变对象,我们不必每次都创建。
静态工厂方法代替构造器在jdk中的运用二:Boolean、Integer、Long、Short、Byte的实例缓存。
在Java自动装箱和自动拆箱 这篇文章中,我就提到了这个问题。
/**
* Returns an {@code Integer} instance representing the specified
* {@code int} value. If a new {@code Integer} instance is not
* required, this method should generally be used in preference to
* the constructor {@link #Integer(int)}, as this method is likely
* to yield significantly better space and time performance by
* caching frequently requested values.
*
* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.
*
* @param i an {@code int} value.
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5
*/
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
/**
* Constructs a newly allocated {@code Integer} object that
* represents the specified {@code int} value.
*
* @param value the value to be represented by the
* {@code Integer} object.
*/
public Integer(int value) {
this.value = value;
}
正如注释所说的,当你不需要创建对象是,使用静态工厂方法:valueOf
而不是构造函数Integer方法
是一个更好的选择,因为它使用了缓存机制来节约创建实例时的时间和空间。
参考文献
《Effective Java中文版 第2版》