静态工厂方法, 也不知道为何叫这个名字. 其实也就是一个静态函数, 可以替代构造函数用. 大名鼎鼎的 https://github.com/google/guava 就大量使用这种模式, 这是非常有用的模式.
比如是
- Integer i = Integer.valueOf(123);
- Boolean bool = Boolean.valueOf(true);
- //guava 的方法
- ConcurrentMap<String,Integer> concurrentMap = Maps.newConcurrentMap();
- ArrayList<Integer> array = Lists.newArrayList(1,2,3,4,5);
那么为什么要用静态工厂方法呢?
《effective java》解释得挺好的, 下面我就进行 "人类的本质", 并加点个人的见解.
静态工厂方法, 有可能不用创建新的对象, 容易缓存
可以去看下 Integer.valueOf 函数
- public static Integer valueOf(int i) {
- if (i>= IntegerCache.low && i <= IntegerCache.high)
- return IntegerCache.cache[i + (-IntegerCache.low)];
- return new Integer(i);
- }
如果是 -128 到 127, 通过 valueOf 构造对象能从对象池中直接获取, 避免了对象重复构建!
如果是 Boolean 对象, 只有 True 和 False 效果就更明显了.
有名字就是好
比如有个 User 类, 有 Name,Address,Email 等字段. 有些数据只需 Name, 和 Email 字段就可以了, 有些字段只需 Name 和 Address 字段就可以了. 但这确实不能创建两个相同类型的构造器! 但你可以创建 newNameWithEmail 或者 newNameWithAddress 的静态工厂函数. 方便!
免去繁琐, 不用写太多的通配符
这个也是被 guava 发扬广大,
比如: 正常构造一个 HashMap
Map<String,List<String>> map = new HashMap<String,List<String>>();
前面类型都定义好了, 为毛还要写 new HashMap<String,List<String>>(); 这样的一大串东西;
而 guava 中只要这样就可以了, 而且还是类型安全的!
Map<String,List<String>> map = Maps.newHashMap();
怎样做到的呢? 看下以前版本的实现.
- public static <K, V> HashMap<K, V> newHashMap() {
- return new HashMap<K,V>();
- }
其实 ,java 官方也发现这个问题的 java 7 在这样一种语法糖
Map<String,List<String>> map = new HashMap<>();
java 9 后 有了 var 语法糖. 可以写成
var map = new HashMap<String,List<String>>();
静态工厂函数的这个优势可有可无了
可以返回原返回类型的任何子类型
比如 EnumSet 根据 universe 数组的长度可以返回不同类型的 EnumSet
- public abstract class EnumSet<E extends Enum<E>> extends AbstractSet<E>
- implements Cloneable, java.io.Serializable {
- EnumSet(Class<E>elementType, Enum[] universe) {
- }
- public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
- if (universe.length <= 64)
- return new RegularEnumSet<>(elementType, universe);
- else
- return new JumboEnumSet<>(elementType, universe);
- }
- }
确实是有点用, 这种用法我是用得比较小. 就觉得 just so so. 遇到这种需求也是比较容易想到的.
静态工厂方法的缺点
个人觉得, 没啥缺点, 甚至觉得每个类最好用静态工厂函数替代构造函数! 最好还是把构造函数变成 private (逃.
这样可以强制不使用继承, 只能用组合.
以上
来源: http://www.bubuko.com/infodetail-2893615.html