item1 · 静态工厂
静态工厂不是设计模式中的工厂方法
例子
public static Boolean valueOf(boolean b) {
return b ? Boolean.TRUE : Boolean.FALSE;
}
优点
-
静态工厂有名字
/** * 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. * * @deprecated * It is rarely appropriate to use this constructor. The static factory * {@link #valueOf(int)} is generally a better choice, as it is * likely to yield significantly better space and time performance. */ @Deprecated(since="9") public Integer(int value) { this.value = value; }
- 使用
Integer.valueOf(123)
比使用new Integer(123)
更为直观 - 源代码中的更好的空间和时间可以见
Integer.vauleOf(int)
的实现(参见下一条)
/** * 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 */ @HotSpotIntrinsicCandidate public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
- 使用
-
不必每次调用都创建一个新对象
- 如
Boolean
示例中valueOf
无需每次创建新对象,因为只存在两种情况 - 如
Integer.valueOf(int)
中使用的IntegerCache
对值为 -128~127 的Integer
对象进行缓存
Integer a = 1000, b = 1000; System.out.println(a == b); // false Integer c = 100, d = 100; System.out.println(c == d); // true
- 如
-
可以返回原返回类型的任何子类型对象
interface Parent { static Parent getChild1(){ return new Child1(); } static Parent getChild2(){ return new Child2(); } } class Child1 implements Parent {} class Child2 implements Parent {}
- Java 8 之后可以支持接口有静态方法(如上)
- 另一例:Java Collections Framework 有45个工具实现,分别提供了不可修改的集合、同步集合,等等。
-
随每次调用而发生变化
interface Parent { static Parent getChild(int i) { return i == 1 ? new Child1() : new Child2(); } } class Child1 implements Parent {} class Child2 implements Parent {}
-
返回的对象所属的类,在编写包含该静态工厂方法的类时可以不存在
- 服务提供者框架的基础
- 例:JDBC
- 服务接口(Service Interface)
Connection
- 提供者注册API (Provider Registration API)
DriverManager.registerDriver
- 服务访问API(Service Access API)
DriverManager.getConnection
- 不同数据库的
Connection
的具体实现是不一样的,通过registerDriver
注册数据库的连接方法到JDBC上,通过getConnection
获得可以使用的Connection
- 服务接口(Service Interface)
缺点
-
类如果不包含公有的或者受保护的构造器,就不能被子类实例化
public class Collections { // Suppresses default constructor, ensuring non-instantiability. private Collections() { } }
-
不容易识别出静态工厂
-
在API文档中没有像构造器那样明确标识出来
-
通过在类或者接口注释中关注静态工厂,并遵守标准的命名习惯
-
from —— 类型转换方法
Date d = Date.from(instant);
-
of —— 聚合方法,带有多个参数
Set<Rank> faceCards = EnumSet.of(JACK, QUEEN, KING);
-
valueOf —— 比 from 和 of 更封锁的一种替代方法
BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE);
-
instance 或 getInstance —— 返回的实例时通过方法的(如有)参数来描述的,但是不能说与参数具有同样的值
StackWalker luke = StackWalker.getInstance(options);
-
create 或 newInstance —— 像instance或者getInstance一样,区别在于每次调用都返回一个新的实例
Object newArray = Array.newInstance(classObject, arrayLen);
-
getType —— 像getInstance一样,但是在工厂方法处于不同的类中的时候使用。Type表示工厂方法所返回的对象类型
FileStore fs = Files.getFileStore(path);
-
newType —— 像newInstance一样,但是在工厂方法处于不同的类中的时候使用
BufferedReader br = Files.newBufferedReader(path);
-
type —— getType和newType的简版
List<Complaint> litany = Collections.list(legacyLitany);
-
-