根据“Effective java”一书,“The class of
静态工厂方法返回的对象甚至不需要存在于
编写包含该方法的类的时间。”表示
以下段落:
解释这句话含义的一个好方法是考虑EnumSet 类型,它是java.util 包中的一个类。
EnumSet 是一个没有任何可访问构造函数的抽象类。为了获得EnumSet 实例,程序员使用其静态工厂方法之一,例如。 EnumSet.of( ... )。例如:
Set<MyEnum> s = EnumSet.of(MyEnum.FIRST_CONSTANT);
of() 方法返回的对象没有EnumSet 的实现类型。相反,实现类型取决于MyEnum 类。如果MyEnum 有64 个或更少的常量,那么of() 返回的对象类型是RegularEnumSet。如果MyClass 的常量超过64 个,则返回的对象类型为JumboEnumSet。然而,返回的对象的实际类型对程序员来说并不重要。他或她所关心的只是获得某种符合EnumSet 合同的对象。
现在,假设五年后,Java 语言架构师决定拥有另一个 EnumSet 实现类型很重要,例如,为具有大量常量(超过 1024 个)。他们编写这个类来遵循EnumSet 合约并调用它:
final CachedEnumSet extends EnumSet {
:
:
}
尽管在编写 EnumSet 时 CachedEnumSet 并不存在,但静态工厂的使用启用了基于合同的实现系统这一事实使 Java 架构师能够在多年后添加这个新的实现。
现在,当客户端调用EnumSet.of() 时,他或她可以获得RegularEnumSet 对象、JumboEnumSet 对象或新的CachedEnumSet 对象,但他们不会在意,因为他们得到的对象是仍然是EnumSet 的子类型,并受其契约约束。