为什么LocalDate、LocalTime和Stream对象使用工厂方法of()而不是构造函数?

7
为什么LocalDateLocalTimeStream等对象使用工厂方法of()而不是构造函数?
我找到了一个解释,为什么应该使用工厂方法而不是new 这里。这个答案给出了很多原因,但唯一与Java日期/时间API相关的是以下内容:
不像构造函数,它们不需要在每次调用时创建一个新对象。
由于LocalDateLocalTime是不可变的,因此使用工厂并重复使用现有对象可能是有意义的,而不是每次都创建一个新对象。
这是为什么像LocalDateLocalTime这样的对象使用工厂方法(即LocalDate.of())的原因吗?还有其他原因吗?
此外,Stream对象是可变的。为什么使用工厂方法(Stream.of())来创建Stream

1
Programmers上关于这个相关问题的答案也可能很有趣。 - Hulk
2个回答

13
为什么要使用工厂方法(Stream.of())来创建流? 使用工厂方法意味着您不需要知道确切使用的类。这是一个很好的例子,因为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

1
谢谢!我已经接受了这个回答,因为它是最受赞同的,但是安迪·特纳的回答回答了我的问题的第二部分。 - Alex

10

+1对Peter的回答。

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

例如, 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第2版》的第1项,则介绍何时和为什么优先使用静态工厂方法而不是构造函数。我在这里提到的“命名构造函数”的优点实际上是Bloch强调的第一个优点。


谢谢!现在清楚了。我的帖子包含了《Effective Java》的摘录/总结链接。我只是看不出这些原则如何应用于Java SE 8 API中。 - Alex
现在我有两个答案,每个答案都回答了我问题的一半。我将会很难选择一个来接受。 - Alex
3
@Alex Peter 显然不缺乏观点,帮帮可怜的我... ;p 别担心,我相信如果你选择另一个人,我们两个都不会感到冒犯。 - Andy Turner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接