供构造函数参考的供应商接口

Supplier interface for constructor reference

以下代码

Supplier<String> newString = String::new;
System.out.println(newString.get());
// prints an empty string (nothing) to the console and then a newline character

并且对于 Supplier get 方法的定义

T get()

get方法应该是returnT,但是constructor没有return类型,为什么String::new可以赋值给Supplier

我想两个例子可以解释它,首先你想要的是一个供应商来打印一个有意义的字符串。喜欢,

Supplier<String> newString = () -> "test";
System.out.println(newString.get());

提供的是一个空字符串。喜欢,

System.out.println(new String());

生成空字符串是完全有效的,即使结果偏离了您的预期。

Bonus 第三个示例,详细说明第一个示例,在 lambda 表达式中,您实际上是在实现 single abstract method from a functional interface - specifically Supplier<T>。喜欢,

Supplier<String> newString = new Supplier<String>() {
    @Override
    public String get() {
        return "test"; // originally return new String()
    }
};
System.out.println(newString.get());

调用构造函数 (new) 创建一个对象并“returns”它,如您所见。

Object object = new Object();

→ 如果构造函数不会 return 任何东西,则此代码是错误的...

但事实并非如此。

所以下面这个例子是可以的

new Thread(new Runnable() {
  @Override public void run() {
    System.out.print("it runs.");
  }
}).start();

也许您一直在阅读有关 constructors 的 Java 教程,其中指出,

Constructor declarations look like method declarations—except that they use the name of the class and have no return type.

这很微妙,但是那句话和 OP 中的陈述有区别。

...constructor has no return type,

请注意,教程指出构造函数 声明 没有 return 类型,这与构造函数本身没有 return 类型的说法略有不同.

声明就是语法;我们可以确认代码中确实没有显示 return 类型。所以没有 explicit return 类型。但是有一个 implicit return 类型,它已经被声明为构造函数的名称。我们根本不需要在声明中重复 return 类型,因为编译器可以从构造函数名称中推断出它。