世界上并没有完美的程序,但是我们并不因此而沮丧,因为写程序就是一个不断追求完美的过程。
以下优点摘抄自Effective Java
1.有名称
2.不必每次调用时都创建一个新对象
3.可以返回原类型的任何子类
4.返回的对象可以随着参数值的不能而变化
5.返回对象的类在编写静态工厂方法时可以不存在
缺点:
1.类如果没有共有构造方法,就不能被子类化
2.程序员很难发现他们
主要用在三个方面
1.类型转换
Date date = Date.from(instance);
Set<Rank> set = EnumSet.of(JACK, QUEEN, KING);
BigInteger big = BigInteger.valueOf(Integer.MAX_VALUE);
2.创建新的类,或时对象重用(对象重用要慎重,有线程不安全的风险)
User user = User.getInstance();
User user = User.newInstance();
3.作为工具类
List<String> list = Collections.list(...);
为了解决子类化的问题,提供公有的构造方法
class UserInfo {
private String id;
private String name;
public UserInfo () {}
public UserInfo (String id, String name) {
this.id = id;
this.name = name;
}
public static UserInfo getInstance () {
return new UserInfo();
}
public static UserInfo getInstance(String id, String name) {
// 可以在创建之前做一些校验
Objects.requireNonNull(id);
Objects.requireNonNull(name);
return new UserInfo(id, name);
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "UserInfo{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
'}';
}
}
参数少时可以用来创建对象,虽然多此一举,但是使用时看起来更优雅一些
(但是根据我的实际使用经验,这样做并不合适,除了代码冗余,没有其他好处,所以还是建议统一使用后面的构建器构建对象,在使用时真的很方便,而且提高了安全性。)
以上括号中的内容是我以前的想法,但是现在发现了使用effective java中推荐的构建器不灵活无法作为实体使用的问题,后来重构,发现静态工厂与构建器的组合才是最优方案,有兴趣的同学可以看一下我的实现方案,虽然比单独的实例多了一点东西,但是在使用时真的很方便,并且很优雅:代码规范-对象的创建-构建器的缺点以及改进
当然静态工厂也有用处,用在对象类型转换上是很不错的,尤其是将其他类型转换为本类型或本类型的相关类型。
还有一个就是作为工具类,并且工具类这样写更好
public final class ToolUtils {
private ToolUtils () {}
public static String convert2String (Object o) {
if (null == o) {
return null;
}
return String.valueOf(o);
}
}
用final修饰类,用private修饰构造器,然后提供静态的工具方法。
以上是我通过学习结合实际工作总结的关于静态工厂方法的用法,也是我将长期坚持的编码准则,希望能够对大家有所帮助。