1 什么是静态工厂方法 静态工厂方法不是指设计模式中的工厂方法,而是在类中提供一个静态方法,该类方法返回类的一个实例。
在Java API中有许多这样的例子,如所有的基本对象的包装类都会提供一个valueOf()的方法用于获取该对象的实例:
String str = String.valueOf(1);
Integer integer = Integer.valueOf("1");
Long lon = Long.valueOf("1");
Double dou = Double.valueOf("1");
2 静态工厂方法的好处 2.1 静态工厂方法可以有名字,而构造方法无法命名 编程中起名字很重要,不管是变量名还是方法名,最好能让人见名知意,易于阅读。比如BigInteger.probablePrime方法,返回一个可能为素数的BigInteger。
在当需要提供多个构造方法,而构造方法之间可能仅仅是参数顺序不一样,这样很容易引发错误。而静态工厂方法完全可以避免这种问题
2.2 静态工厂方法不一定要创建一个新对象 【effective|Item1: 考虑使用静态工厂方法代替构造方法】这一点在单例模式中有很好的体现。通过将构造方法私有,再提供一个静态方法每次返回同一个实例。
还有一种常见的情况,如果对象的创建成本很高,为了提高效率,不会每次都创建一个新对象,而是使用对象池,将用完的对象放入该池中,当需要一个对象时,通过静态工厂方法返回,方法内部判断对象池中是否有空闲对象,如果没有再创建新对象。
2.3 静态工厂方法可以返回其返回类型的任何子类 首先来看例子:
List
源码:
public static final List EMPTY_LIST = new EmptyList<>();
public static final List emptyList() {
return (List) EMPTY_LIST;
}
private static class EmptyList
extends AbstractList
implements RandomAccess, Serializable {
private static final long serialVersionUID = 8842843931221139166L;
public Iterator iterator() {
return emptyIterator();
}
public ListIterator listIterator() {
return emptyListIterator();
}public int size() {return 0;
}
public boolean isEmpty() {return true;
}public boolean contains(Object obj) {return false;
}
public boolean containsAll(Collection> c) { return c.isEmpty();
}
public int hashCode() { return 1;
}
}
在源码中可以看到,该方法返回的是一个常量,而该常量是通过创建一个EmptyList对象,它是List的一个子类。
一般而言,对于一个接口Type(如这里的Collection),会提个一个Types的类(如这里的Collections),该类会提供私有构造方法,通过静态工厂方法放回示例,而其中大部分的类都对外隐藏,如上面看到的EmptyList类别设置为private。这样会使整个API更为紧凑。且当下次我要修改EmptyList的实现时,对使用者没有影响。
2.4 返回对象的类可以根据输入参数的不同而不同 2.5 返回对象的类不需要存在 3 缺点
- 当构造方法被私有时,无法被继承(这个点倒是没有很理解,不私有构造方法就可以解决这个问题)
- 程序员无法找到静态工厂方法。主要是指java doc不会把静态公共方法和构造方法放在一起,二是将其和其他普通方法放在一起
- from
- of
- valueOf
- instance/getInstance
- create/newInstance
- getXxxx
- newXxxx
推荐阅读
- Java|Java基础——数组
- 人工智能|干货!人体姿态估计与运动预测
- java简介|Java是什么(Java能用来干什么?)
- Java|规范的打印日志
- Linux|109 个实用 shell 脚本
- 程序员|【高级Java架构师系统学习】毕业一年萌新的Java大厂面经,最新整理
- Spring注解驱动第十讲--@Autowired使用
- SqlServer|sql server的UPDLOCK、HOLDLOCK试验
- jvm|【JVM】JVM08(java内存模型解析[JMM])
- 技术|为参加2021年蓝桥杯Java软件开发大学B组细心整理常见基础知识、搜索和常用算法解析例题(持续更新...)