【问题标题】:Why LocalDate, LocalTime and Stream objects use a factory method of() instead of a constructor?为什么 LocalDate、LocalTime 和 Stream 对象使用工厂方法 of() 而不是构造函数?
【发布时间】:2016-07-17 18:03:02
【问题描述】:

为什么LocalDateLocalTimeStream等对象使用工厂方法of()而不是构造函数?

我找到了为什么应该使用工厂方法而不是 new here 的解释。这个答案给出了许多原因,但与 Java 日期/时间 API 相关的唯一原因如下:

与构造函数不同,它们不需要每次都创建一个新对象 它们被调用的时间

由于LocalDateLocalTime 是不可变的,因此使用工厂并重用现有对象而不是每次都创建新对象可能更有意义。

这就是像LocalDateLocalTime 这样的对象是用工厂方法(即LocalDate.of())创建的原因吗?还有其他原因吗?

另外,Stream 对象是可变的。为什么使用工厂方法(Stream.of())来创建Stream

【问题讨论】:

标签: java java-8 factory factory-method


【解决方案1】:

为什么使用工厂方法 (Stream.of()) 来创建 Stream?

使用工厂方法意味着您不需要知道所使用的确切类。这是一个很好的例子,因为Stream 是一个接口,你不能创建一个接口的实例。

来自Stream.of的来源

/**
 * Returns a sequential {@code Stream} containing a single element.
 *
 * @param t the single element
 * @param <T> the type of stream elements
 * @return a singleton sequential stream
 */
public static<T> Stream<T> of(T t) {
    return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
}

/**
 * Returns a sequential ordered stream whose elements are the specified values.
 *
 * @param <T> the type of stream elements
 * @param values the elements of the new stream
 * @return the new stream
 */
@SafeVarargs
@SuppressWarnings("varargs") // Creating a stream from an array is safe
public static<T> Stream<T> of(T... values) {
    return Arrays.stream(values);
}

注意:这些方法调用其他工厂方法。

你可以看到你得到不同的结构,这取决于它是如何被调用的。你不需要知道这个或那个创建的终极类是 ReferencePipeline.Head

【讨论】:

  • 谢谢!我认为这个答案是最受推崇的,但安迪·特纳的答案回答了我问题的第二部分。
【解决方案2】:

+1 彼得的回答。

使用工厂方法的另一个原因是它们的行为类似于“命名构造函数”。

例如,LocalDate 有 6 个静态工厂方法(至少,我这里可能不详尽):

  • of(int year, int/Month month, int dayOfMonth)(两个重载)
  • ofEpochDay(long epochDay)
  • ofYearDay(int year, int dayOfYear)
  • parse(CharSequence text)
  • parse(CharSequence text, DateTimeFormatter formatter)

我认为通过将它们作为单独命名的方法而不是一堆具有非常相似的参数类型的构造函数来理解各种参数的含义要清楚得多;您几乎可以猜到工厂方法的参数应该是什么,而如果它们是“未命名的”构造函数,您实际上可能必须阅读 Javadoc(令人震惊)。

诚然,of 是这些名称中最不清晰的——有人可能想要ofYearMonthDayOfMonth——但是,我怀疑这是最常用的工厂方法,而且在所有名称中都输入那个长名称太混乱了时间。


如果您还没有读过它,Effective Java 2nd Edition 的第 1 条就是关于为什么以及何时更喜欢静态工厂方法而不是构造函数。我这里提到的“命名构造函数”优势实际上是布洛赫强调的第一个优势。

【讨论】:

  • 谢谢!现在很清楚了。我的帖子包含指向有效 Java 的摘录/摘要的链接。我只是看不出这些原则是如何在 Java SE 8 API 中应用的。
  • 现在我有两个答案,每个答案都回答了我一半的问题。我很难选择接受)
  • @Alex Peter 显然不缺一两点,帮助可怜的小我... ;p 别担心,如果你选择另一个,我相信我们都不会被冒犯.
猜你喜欢
  • 2010-10-25
  • 2014-02-18
  • 1970-01-01
  • 2014-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
相关资源
最近更新 更多