2.1-创建和销毁对象-考虑使用静态工厂方法替代构造方法

Item 1:考虑使用静态工厂方法替代构造方法

注意:这里的静态工厂方法static factory method和设计模式中的工厂方法模式Factory Method pattern不等价。

优点

有方法名,便于用于阅读和理解

更加语义化。

特别是有多个构造函数时,容易错误的调用。静态工厂方法有方法名,很容易辨识。

不必每次调用时都创建一个新对象

  1. 允许不可变的类immutable classes使用预先构建的实例。

  2. 构造时缓存实例,避免创建不必要的重复对象。

    可以提高性能,尤其是那种创建他们非常昂贵的情况(耗性能)下。

与构造方法不同,可以返回原类型的子类对象

这个子类可以是隐藏的,即非公开的内部类或包私有类。

例子:java.util.Collections里有很多内部的集合。

返回对象所属类可以根据输入参数变化而变化

举例:EnumSet类的静态工厂方法noneOf方法。如果大多数枚举类型具有64个或更少的元素,静态工厂将返回一个RegularEnumSet实例, 返回一个long类型;如果枚举类型具有六十五个或更多元素,则工厂将返回一个JumboEnumSet实例,返回一个long类型的数组。

这两个实现类的存在对于客户是不可见的。

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

SPI。静态构造方法返回的是该子类对象,但接受的是接口。

举例:JDBC

缺点

只提供静态工厂方法,则没有public/protected构造方法的类不能被子类化

通过继承创建子类。由于子类的构造中要调用父类的构造。因此父类没有public/protected的构造方法则无法子类化。

可以通过组合实现。

很难让开发者找到

不能像构造方法那么突出。可以通过Javadoc标注。

静态工厂方法常用命名

  • from:类型转换方法。接受单个参数并返回此类型的相应实例。

    1
    Date d = Date.from(instant);
  • of:聚合方法,接受多个参数并返回该类型的实例。

    1
    Set<Rank> faceCards = EnumSet.of(JACK, QUEEN, KING)
  • valueOffromof更为详细的替代方法。

    1
    BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE);
  • instance或者getInstance:返回一个由其参数(如果有的话)描述的实例,但不能说它具有相同的值。

    1
    StackWalker luke = StackWalker.getInstance(options);
  • create或者newInstance:与instancegetInstance类似,除了该方法保证每个调用返回一个新的实例

    1
    Object newArray = Array.newInstance(classObject, arrayLen);

    区别:create或者newInstance每次调用都返回新的实例。instance或者getInstance不一定。

  • getType:和getInstance类似,在工厂方法处于不同的类中的时候使用。

    1
    FileStore fs = Files.getFileStore(path);
  • newType:和newInstance类似,在工厂方法处于不同的类中的时候使用。

    1
    BufferedReader br = Files.newBufferedReader(path);
  • typegetTypenewType简洁的替代方式。

    1
    List<Complaint> litany = Collections.list(legacyLitany);
-------------本文结束感谢您的阅读-------------
0%