Java 8 能否动态实现接口以供方法参考?

Can Java 8 implement interface on the fly for method reference?

我学习了Java8.

的新特性

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

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();
}

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

来自the Java Tutorial,有四种方法参考:

Kind                              Example
-------------------------------   ------------------------------------
Reference to a static method      ContainingClass::staticMethodName
Reference to an instance method   containingObject::instanceMethodName
of a particular object  
Reference to an instance method   ContainingType::methodName
of an arbitrary object of a 
particular type
Reference to a constructor        ClassName::new

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

  • 不接受任何参数;
  • returns一个对象。

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

这里所说的方法是方法参考。它不带任何参数和 returns Test 的新实例。您可以将其重写为:

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

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

Test::new是方法参考。与其添加新的解释,还不如看看 method references 的教程,因为它解释得很好。

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

有四种方法引用:查看教程以了解所有内容。