为什么在Java中没有用于Optional的公共构造函数?

时间:2018-12-02 11:48:36

标签: java constructor java-8 optional

为什么Optional具有of()ofNullable()之类的方法而不是公共构造函数?

4 个答案:

答案 0 :(得分:37)

来自有效的Java Joshua Bloch,第2章。创建和销毁 对象,1个物品:

  

考虑静态工厂方法而不是构造方法

为什么?

  

静态工厂方法的一个优点是,与构造函数不同,   他们有名字。

使用静态工厂方法,我们可以在方法定义中指定一些实例化行为。这样可以简化API的使用,并且可以防止客户端调用错误的构造函数。

例如在这里:在Optional.ofNullable->中,我们允许传递空值以实例化Optional,在Optional.of中,不允许空值并引发异常。我们不能在这里使用构造函数。

private Optional(T value) {
    this.value = Objects.requireNonNull(value); //this throws NullPointerException
}
public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
}
public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
} 

另一个优势(已经提到):

  

静态工厂方法的第二个优点是,与   构造函数,不需要每次都创建一个新对象   它们被调用。

在Optional中,空值仅被实例化一次,然后存储在静态字段中,当程序需要一个空值时,总是重复使用该值。

private static final Optional<?> EMPTY = new Optional<>(); //instantiate value when program starts

public static<T> Optional<T> empty() {
    @SuppressWarnings("unchecked")
    Optional<T> t = (Optional<T>) EMPTY; //return stored value when requested
    return t;
}

答案 1 :(得分:21)

原因实际上很简单:空的可选内容是静态常量,可以提高内存效率。如果使用了构造函数,则在常见情况下每次都必须创建一个新实例。

public static<T> Optional<T> empty() {
    @SuppressWarnings("unchecked")
    Optional<T> t = (Optional<T>) EMPTY;
    return t;
}

public static <T> Optional<T> ofNullable(T value) {
    return value == null ? empty() : of(value);
}

答案 2 :(得分:9)

可选的是Value-based Class,没有任何构造函数

  

没有可访问的构造函数,而是通过工厂方法实例化的,这些方法不对返回的实例的身份进行确认

答案 3 :(得分:9)

因为当已知可能的实例化情况时,应该比公共构造方法更喜欢工厂方法。
它使API更易于用于客户端类。
除了工厂方法外,还可以决定是否应在每次调用时创建实例。
Optional.empty()的情况下,有意义的是缓存该值,因为它是不可变的。