java - 可作为方法参考运行
问题描述
为什么这段代码不能编译?无法完全掌握细微差别的 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 !!
}
}
解决方案
这里有一些误解,其他答案只提供最终结果。所以这里有一个真实的解释。
在 java 中,有 lambda ( () -> something
) 和方法引用 ( Class::method
)。它们基本上是一样的,只是语法不同(更短)。如果您愿意,您可以混合使用 lambda 和方法引用(lambda 中的 lambda,lambda 中的方法引用)。只要一切都是正确的类型,你就可以了。
类型的System.out::println
方法引用也是如此Consumer<String>
,原因作为参数,并返回- 那是. (也有不带参数的,在这种情况下它是 a )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
}
但这有点没有意义。
所以你可以清楚地看到,这() -> System.out::println()
实际上是一个提供Runnable
or的 lambda Consumer<String>
,所以它的类型应该是
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
不如你解释一下你想做什么,我们会帮你的。
推荐阅读
- android - 如何在Android中制作闪烁的imageview?
- css - 如何在 react-bootstrap 中删除悬停效果并更改活动选项卡的颜色?
- list - 保存从 Firestore 集合中的 JSON URL 获取的列表
- jena - Apache Jena:将 GraphNode(N3 公式)添加到模型(ARQInternalErrorException)
- c# - 如何在 C#“object.equals”中使用“或”(|)运算符
- python - 如何在 Python 中对 LSTM 神经网络进行模型不可知论?
- python - tesseract 在白名单后无法识别单个文本段
- python - 即使在我安装之后也无法导入 numpy?
- python - 如何在 python 中读取 JSON 文件作为具有特定格式的块的流
- jdbc - 在 OpenLiberty 中为 Arquillain 测试配置默认数据源