写点什么

创建和销毁对象 - 考虑用静态工厂方法代替构造器,熬夜整理出 Java 后端学习路线

用户头像
极客good
关注
发布于: 刚刚

if (i >= IntegerCache.low && i <= IntegerCache.high)

return IntegerCache.cache[i + (-IntegerCache.low)];

return new Integer(i);

}

复制代码

而当我们使用`valueOf`的时候,Java 会为在落入`IntegerCache`中的数字返回相同的对象,这样就避免了创建不必要的重复对象,可以极大地提升性能!但是需要注意的是,这样有可能造成部分基础不熟练的同事使用==对`Integer`进行判断,当返回结果落入`IntegerCache`的时候不会有不相等的问题,因为都是同一个对象,但是如果真实环境超过了\[-128, 127\](127 可以通过参数设置),那么这时候可能就会不一样了,会有潜在的 bug 隐患。

可以返回原返回类型的任何子类型的对象

------------------

你可以返回你想返回的任何子类。一种应用是使得 API 可以返回对象,同时也不会是对象的类变成公有地。用这种方式隐藏实现类会使接口变得非常简洁。

Java 8 之前,接口中不能有静态方法,这时候我们都是依靠不可实现类来实现的

Java8 之后,我们的接口中可以有静态方法了,所以此时为接口提供不可实现类已经只是因为接口中的静态方法必须是`public`的。Java 9 中静态方法可以是`private` 的了,但是字段仍然需要是`public`的。

返回类可随参数而变

---------

每次调用的时候如果我们愿意,是可以通过静态工厂方法的参数值决定返回父类的哪种子类的,构造器就做不到这一点。

`java.util.EnumSet` 这个就体现了这一点,`EnumSet`被声明为`abstract class`类型,`EnumSet`有两种实现方式,`RegularEnumSet`和`JumboEnumSet`,但是这两种实现方式是包私有的,不能在包外访问,因此必须使用工厂方法来创建并返回`EnumSet`实例,不能通过构造函数来创建。

//noneOf 方法

public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {

Enum<?>[] universe = getUniverse(elementType);

if (universe == null)

throw new ClassCastException(elementType + " not an enum");

if (universe.length <= 64)

return new RegularEnumSet<>(elementType, universe);

else

return new JumboEnumSet<>(elementType, universe);

}

复制代码

如果数量小于等于 64,我们使用`RegularEnumSet`,如果大于 64 时,我们使用`JumboEnumSet`,使用者无需关心返回的是哪种子类,只要能用就行,甚至我们以后新加子类也对使用者没有影响!这也是为什么我们使用静态工厂来进行创建的原因。 [noahsnail.com/2016/09/27/…](

)

返回对象所属的类,在编写包含该静态工厂方法的类时可不存在

----------------------------

这是服务提供者框架的基础,比如 JDBC 的 API 就是如此,多个服务提供者实现一个服务,系统为服务提供者的客户端提供多个实现,并把他们从多个实现中解耦出来。

缺点

==

类可能无法子类化

--------

类如果没有 public 或者 protect 修饰的构造器,就不能被子类化,不过这样也好,我们最好使用复合而不是继承。

静态工厂方法太不起眼

----------

一眼看过去,静态工厂方法和静态方法没有什么区别的,比如,如果我们想要查明如何实现一个 EnumSet,在不搜索的情况下可能会发现直接 new 不行。对我们查明如何实例化类会有些困难。

作者:临时营地

用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
创建和销毁对象-考虑用静态工厂方法代替构造器,熬夜整理出Java后端学习路线