为什么LocalDate
,LocalTime
,Stream
等对象使用工厂方法of()
而不是构造函数?
我找到了为什么应该使用工厂方法而不是new
here的解释。这个答案有很多原因,但与Java Date / Time API相关的唯一原因如下:
与构造函数不同,它们不需要分别创建新对象 他们被调用的时间
由于LocalDate
和LocalTime
是不可变的,因此使用工厂并重用现有对象而不是每次都创建新对象可能是有意义的。
这就是使用工厂方法(即LocalDate
)创建像LocalTime
和LocalDate.of()
这样的对象的原因吗?还有其他原因吗?
此外,Stream
个对象是可变的。为什么使用工厂方法(Stream.of()
)来创建Stream
?
答案 0 :(得分:11)
为什么使用工厂方法(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
答案 1 :(得分:8)
+1给彼得的答案。
使用工厂方法的另一个原因是它们的行为类似于#34;命名构造函数&#34;。
例如,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(震惊恐怖),如果它们是&#34;未命名&#34;构造
不可否认,of
是这些名称中最不清楚的 - 人们可能想要ofYearMonthDayOfMonth
- 但是,我怀疑这是最常用的工厂方法,而且它也是总是把这个长名字弄得一团糟。
如果您还没有阅读它, Effective Java 2nd Edition 的第1项就是为什么以及何时更喜欢静态工厂方法而不是构造函数。 &#34;命名的构造函数&#34;我在这里提到的优势实际上是Bloch亮点的第一个优势。