此处的静态工厂方法有别于设计模式中的工厂模式:泛指能够返回类的一个实例的静态方法。例如Boolean的valueOf方法:
/**
* The {@code Boolean} object corresponding to the primitive
* value {@code true}.
*/
public static final Boolean TRUE = new Boolean(true);
/**
* The {@code Boolean} object corresponding to the primitive
* value {@code false}.
*/
public static final Boolean FALSE = new Boolean(false);
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
使用静态工厂方法代替构造器的好处有:
1、方法有名称:通过正确命名可以更确切地描述返回的实例对象,使代码更易阅读。
2、不会在每次调用时都创建新对象。静态工厂方法会预先构建好对象或缓存对象,已达到重复利用对象的目的,避免过多地创建不必要的对象。在频繁请求创建同一个对象的情况下,能一定程度地提升性能。
3、可以返回原返回类的任意子类的对象。
服务者提供框架例子:
//服务提供者接口,用来提供服务
//这个接口时可选的,如果没有,下面的Map集合就可以直接存放Service对象
public interface Provider {
Service newService();
}
//服务接口, 用来写具体的服务内容
public interface Service {
// Service-specific methods go here
}
public class Services {
private Services() {
} // Prevents instantiation (Item 4)
// Maps service names to services
//服务的注册和访问
//用一个Map来存放提供这的名字和提供者的对象
private static final Map<String, Provider> providers = new ConcurrentHashMap<String, Provider>();
public static final String DEFAULT_PROVIDER_NAME = "<def>";
// Provider registration API
//注册默认的提供者
public static void registerDefaultProvider(Provider p) {
registerProvider(DEFAULT_PROVIDER_NAME, p);
}
//所谓注册就是在加入Map
public static void registerProvider(String name, Provider p) {
providers.put(name, p);
}
// Service access API
//使用这个方法创建实例
public static Service newInstance() {
return newInstance(DEFAULT_PROVIDER_NAME);
}
//创建的时候看缓存里有没有provider
public static Service newInstance(String name) {
Provider p = providers.get(name);
if (p == null)
throw new IllegalArgumentException(
"No provider registered with name: " + name);
return p.newService();
}
}
测试:
public class TestNo1 {
public static void main(String[] args) {
//测试的时候先注册,然后在再创建相应地对象,这里的provider使用内部类
//由provider返回具体的service实例
// Providers would execute these lines
Services.registerDefaultProvider(DEFAULT_PROVIDER);
Services.registerProvider("comp", COMP_PROVIDER);
Services.registerProvider("armed", ARMED_PROVIDER);
// Clients would execute these lines
//调用Service的toString方法
Service s1 = Services.newInstance();
Service s2 = Services.newInstance("comp");
Service s3 = Services.newInstance("armed");
System.out.printf("%s, %s, %s", s1, s2, s3);
}
//Provider的匿名内部类
private static Provider DEFAULT_PROVIDER = new Provider() {
public Service newService() {
//Service的匿名内部类
return new Service() {
@Override
public String toString() {
return "Default service";
}
};
}
};
private static Provider COMP_PROVIDER = new Provider() {
public Service newService() {
return new Service() {
@Override
public String toString() {
return "Complementary service";
}
};
}
};
private static Provider ARMED_PROVIDER = new Provider() {
public Service newService() {
return new Service() {
@Override
public String toString() {
return "Armed service";
}
};
}
};
}
4、在创建参数化类型实例时,能使代码更简洁。
以上为使用静态工厂方法创建实例的优势。看着跟策略模式很像哈。