And*_*ndy 3 java lambda java-8 method-reference
为什么这段代码不能编译?无法完全掌握 java 方法参考的细微差别:(
public class TestClass {
static void println() {}
public static void main(String[] args) {
Runnable r1 = () -> System.out::println; // compilation error
Runnable r2 = () -> TestClass::println; // compilation error
Runnable r2 = () -> System.out.println("Hello World"); // This is fine !!
}
}
Run Code Online (Sandbox Code Playgroud)
这里有一些误解,其他答案仅提供最终结果。所以这是一个真正的解释。
在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.
至于为什么你的代码是编译错误:
将 a 声明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
}
Run Code Online (Sandbox Code Playgroud)
但这有点没有意义。
所以你可以清楚地看到,这() -> System.out::println()实际上是一个提供Runnableor的 lambda Consumer<String>,所以它的类型应该是
Supplier<Runnable> s = () -> System.out::println; // either this
Supplier<Consumer<String>> s = () -> System.out::println; // or this
Run Code Online (Sandbox Code Playgroud)
要直接使用它,你只需要放弃 Supplier<>
Runnable s = System.out::println; // either this
Consumer<String> s = System.out::println; // or this
Run Code Online (Sandbox Code Playgroud)
您只需解释一下您想要做什么,我们就会帮助您。
| 归档时间: |
|
| 查看次数: |
132 次 |
| 最近记录: |