19

我学习了 Java 8 的新特性。

我正在玩不同的例子,我发现了一个奇怪的行为:

public static void main(String[] args) {       
    method(Test::new);
}
static class Test{
}

private static void method(Supplier<Test> testSupplier){
    Test test = testSupplier.get();
}

这段代码编译成功,但我不知道它是如何工作的。

为什么Test::new可以作为供应商接受?

供应商界面看起来很简单:

@FunctionalInterface
public interface Supplier<T> {    
    T get();
}
4

3 回答 3

19

Supplier接口有一个(功能)方法:

  • 不带任何参数;
  • 返回一个对象。

因此,任何符合这两点的方法,都符合的功能契约Supplier(因为方法将具有相同的签名)。

这里,所讨论的方法是方法参考。它不接受任何参数并返回一个新的Test. 您可以将其重写为:

method(() -> new Test());

Test::new在这个 lambda 表达式的语法糖中。

于 2015-09-21T20:33:02.990 回答
11

Test::new是方法参考。与其添加新的解释,不如看一下方法参考教程,因为它很好地解释了它们。

您的问题的直接答案是这Supplier是一个功能接口 - 这意味着它有一个非默认方法。for 的构造函数Test具有完全相同的签名(无参数,返回Test),因此可以直接引用以创建匿名Supplier

有四种方法参考:查看教程以了解它们。

于 2015-09-21T20:33:04.410 回答
3

如果需要参数,它可能是Function,而不是供应商。但是方法引用可以像引用方法一样引用构造函数;他们只是有一个有趣的名字(new)。

Java 教程中,有四种方法引用:

样例
------------------------------------------- -------- -----------------
引用静态方法 ContainingClass::staticMethodName
引用包含Object::instanceMethodName 的实例方法
特定对象的  
引用实例方法 ContainingType::methodName
a 的任意对象
特定类型
对构造函数 ClassName::new 的引用
于 2015-09-21T20:31:45.017 回答