构造器就是类的构造方法,名称与类名相同,只是方法参数不一样;
静态工厂方法就是一个返回类的实例的静态方法,例如Boolean类中的valueOf方法:
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
例如,BigInteger类中,构造器BigInteger(int, int, Random)可能返回一个素数,但是对于调用者来说不清晰;如果用名为BigInteger.probablePrime静态工厂方法来表示,显得更清楚。
再举一个JDK的例子:Executors类,在这个类中有newFixedThread、newSingleThreadExecutor、newCachedThreadPool等静态方法,因为它们有“名字”,所有就较为清晰的明白API的含义。
public class Instance() {
private static Instance instance = new Instance();
private Instance(){}
public static Instance getInstance() {
return instance;
}
}
举个JDK中的例子:Collections类
List list = Collections.synchronizedList(new ArrayList())
这个例子就说明了可以返回原返回类型的任何子类型的对象。
结合优势三,意思就是,可以返回不同的子类对象,这些子类对象对客户端来说是不可见的,因此可以灵活地按需返回不同的子类对象。
TODO
例如,要想将Collection Framework中的任何便利的实现类子类化,这是不可能的。但是这样也许会因祸得福,因为它鼓励程序员使用复合(composition),而不是继承,这正是不可变类型所需要的。
在API文档中,静态工厂方法没有像构造器那样在API文档中明确标识出来,因此,对于提供了静态工厂方法而不是构造器的类来说,要想查明如何实例化一个类是非常困难的。
静态工厂方法的一些惯用名称:
只有单个参数,返回该类型的一个相对应的实例,例如
Date d = Date.from(instant);
带有多个参数,返回该类型的一个实例,把它们合并起来,例如
Set<Rank> faceCards = EnumSet.of(JACK,QUEEN,KING);
BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE);
返回的实例时通过方法的(如有)参数来描述的,但是不能说与参数具有同样的值,例如
StackWalker luke = StackWalker.getInstance(options);
像instance或者getInstance一样,区别在于每次调用都返回一个新的实例,例如:
Object newArray = Array.newInstance(classObject,arrayLen);
Type
像getInstance一样,但是在工厂方法处于不同的类中的时候使用。Type表示工厂方法所返回的对象类型,例如:
FileStore fs = Files.getFileStore(path);
Type
像newInstance一样,但是在工厂方法处于不同的类中的时候使用。Type表示工厂方法所返回的对象类型,例如:
BufferedReader br = Files.newBufferedReader(path);
Type
getType
和newType
的简版,例如
List<Complaint> litany = Collections.list(LegacyLitany);