这里有一点误解,其他答案只提供最终结果。所以这里有一个真实的解释。
在 java 中,有 lambdas (() -> something) 和方法引用 (Class::method)。它们基本上是一样的,只是语法不同(更短)。如果您愿意,您可以混合使用 lambda 和方法引用(lambda 中的 lambda,lambda 中的方法引用)。只要一切都是正确的类型,就可以了。
所以System.out::println 是Consumer<String> 类型的方法引用,因为System.out.println() 将String 作为参数,并返回void - 那是Consumer<String>。 (还有 System.out.println() 不带参数,在这种情况下,它会是 Runnable)
Runnable 有点不同,因为它不接收任何参数或返回值。例如List::clear。
至于为什么你的代码是编译错误:
当将 Runnable 声明为 lambda 时,您必须不接收任何参数并返回 void。这个 lambda:Runnable r1 = () -> System.out::println; 不符合条件,因为它不接收任何参数 (() ->),但它的表达式确实返回一个类型 - Consumer<String>(或再次Runnable),而不是void。如果您设法不返回任何内容,则它可能是有效的Runnable,例如
Runnable r1 = () -> {
Consumer<String> str1 = System.out::println; // either this
Runnable str2 = System.out::println; // or this
return; // return type - void
}
但这有点没有意义。
所以你可以清楚地看到,() -> System.out::println() 实际上是一个提供 Runnable 或 Consumer<String> 的 lambda,所以它的类型应该是
Supplier<Runnable> s = () -> System.out::println; // either this
Supplier<Consumer<String>> s = () -> System.out::println; // or this
要直接使用它,你只需要放弃Supplier<>
Runnable s = System.out::println; // either this
Consumer<String> s = System.out::println; // or this
您只需解释一下您要做什么,我们会为您提供帮助。