runnable作为方法引用

gmol1639  于 2021-07-03  发布在  Java
关注(0)|答案(5)|浏览(445)

为什么这段代码不能编译?无法完全掌握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 !!

    }
}
5q4ezhmt

5q4ezhmt1#

它应该是一个“直接”的方法引用,而不是一个方法引用所代表的东西的提供者。

Runnable r1 = System.out::println;
Runnable r2 = TestClass::println;

比较

Supplier<Runnable> a = () -> System.out::println;

具有

Runnable b = System.out::println;
vngu2lb8

vngu2lb82#

在本例中,system.out.println是一个使用者(它接受一个字符串并用它做一些事情)

Consumer<String> c = System.out::println;

    List<String> strings = Arrays.asList("Whee", "Boo");
    strings.forEach(c);  <-- We then pass this consumer here.

或无:

List<String> strings = Arrays.asList("Whee", "Boo");

    strings.forEach(element -> System.out.println(element)); <-- without method reference

    strings.forEach(System.out::println);
g6baxovj

g6baxovj3#

方法引用不是这样工作的。你这样使用它们:

Runnable r1 = System.out::println;
zz2j4svz

zz2j4svz4#

因为你需要这样写:

Runnable r1 = System.out::println;
Runnable r2 = TestClass::println;

在这里您可以阅读更多关于方法引用的信息https://docs.oracle.com/javase/tutorial/java/javaoo/methodreferences.html

64jmpszr

64jmpszr5#

这里有一点误解,其他答案只能提供最终结果。所以这里有一个真正的解释。
在java中,有lambda( () -> 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> ,所以它的类型应该是

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 s = System.out::println; // or this

不如你解释一下你想做什么,我们会帮你的。

相关问题