Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么java中没有可选的公共构造函数?_Java_Constructor_Java 8_Optional - Fatal编程技术网

为什么java中没有可选的公共构造函数?

为什么java中没有可选的公共构造函数?,java,constructor,java-8,optional,Java,Constructor,Java 8,Optional,为什么Optional有像of()和of nullable()这样的方法而不是公共构造函数?Optional是一个没有任何构造函数的方法 没有可访问的构造函数,而是通过工厂方法进行实例化,工厂方法对返回实例的标识不做任何承诺 因为在已知可能的实例化情况时,工厂方法应该优于公共构造函数。 它使API更易于用于客户端类。 此外,工厂方法允许决定是否应在每次调用时创建实例。 在这种情况下,缓存该值是有意义的,因为它是不可变的 原因其实很简单:一个空的可选值是一个静态常量,以提高内存效率。如果使用了构造

为什么
Optional
有像
of()
of nullable()
这样的方法而不是公共构造函数?

Optional是一个没有任何构造函数的方法

没有可访问的构造函数,而是通过工厂方法进行实例化,工厂方法对返回实例的标识不做任何承诺


因为在已知可能的实例化情况时,工厂方法应该优于公共构造函数。
它使API更易于用于客户端类。
此外,工厂方法允许决定是否应在每次调用时创建实例。

在这种情况下,缓存该值是有意义的,因为它是不可变的

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

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);
}
公共静态可选空(){
@抑制警告(“未选中”)
可选t=(可选)空;
返回t;
}
公共静态可选未满(T值){
返回值==null?空():of(值);
}

摘自Joshua Bloch《有效Java》,第2章。创造与毁灭 对象,1项:

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

为什么?

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

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

例如这里:In->我们允许传递null值来实例化,In null值不允许并抛出异常。我们不能在这里使用构造函数

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);
} 
private可选(T值){
this.value=Objects.requirennoull(value);//这会引发NullPointerException
}
公共静态可选值(T值){
返回新的可选值;
}
公共静态可选未满(T值){
返回值==null?空():of(值);
} 
另一个优点(已经提到):

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

在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;
}
private static final Optional EMPTY=new Optional()//当程序启动时实例化值
公共静态可选空(){
@抑制警告(“未选中”)
可选t=(可选)EMPTY;//请求时返回存储值
返回t;
}

因为empty是内存效率的一个单例。因为如何创建一个
可选的
是一个实现细节,OP知道这一点。他在问为什么会这样。@jbnize你认为OP真的会问:为什么基于值的类没有可访问的构造函数?不。我想他问为什么Optional的设计者选择不向Optional添加公共构造函数。回答这个可选的是一个值类,因此没有公共构造函数并不能回答这个问题,IMHO。@JBNizet:我认为它确实从技术上回答了这个问题,但打开了其他问题:“什么是值类”和“值类的优点是什么”。如果它也包含了大量的信息,这个答案会更好。请看一看:不要忘记:的
的名称不仅记录了这两个工厂的不同语义,而且使它们成为可能,因为我们有两种具有相同类型签名的方法,因此,需要不同的名称才能在同一个类中声明它们。由于构造函数没有名称,所以不可能用相同的参数类型声明其中的两个。当然,他的意思是在公共API上。我的意思是,很明显,你最终需要有构造器,它不能只是一个无止境的工厂方法链。。。或者可以吗?!拥有一个公共构造函数并不妨碍拥有一个返回单例实例的静态方法。我没有说会是这种情况,我只是回答了这个问题。“如果使用了构造函数,它每次都必须为一个普通实例创建一个新实例。”-对我来说,这意味着你必须使用构造函数而不是工厂方法。也许您可以将其改写为清楚的一点,即拥有公共构造函数意味着人们更有可能创建重复的空实例?