Java 8+如何推断方法引用为使用者?

时间:2019-01-19 16:33:35

标签: java lambda java-8

我正在探索与JDK 8相关的一些新事物,特别是Refrence方法和Iterable的新forEach方法,如下所示:-

public class Runner {

    public static void main(String[] args) {
        String[] testArgs = new String[]{"test","123","456"};
        Arrays.asList(testArgs).forEach(Runner::test);
    }

    public static String test(String s) {
        System.out.println(s);
        return s;
    }

}

这可以按要求工作,但是正如我在forEach中看到的java.lang.Iterable方法一样,如下所示,接受并期望Consumer<? super T> action

default void forEach(Consumer<? super T> action) {
    Objects.requireNonNull(action);
    for (T t : this) {
        action.accept(t);
    }
}

现在要提出一个问题-> JDK如何将method reference作为Consumer类型?

1 个答案:

答案 0 :(得分:1)

Java-8编译器查看涉及的方法声明:

    界面public void forEach(Consumer<? super T>中的
  • Iterable<T>
  • 界面public void accept(T t)中的
  • Consumer<T>
  • public static String test(String)在您的课程Runner

从所有这些结论中可以得出结论,Consumer<String>是合适的。

因此,它扩展了方法引用Runner::test 接口Consumer<String>的实现的委托 转到方法test(String)

Arrays.asList(testArgs).forEach(Runner::test);

扩展为与此等效的内容:

Arrays.asList(testArgs).forEach(new Consumer<String>() {        
    @Override
    public void accept(String t) {
        test(t);
    }
});

实际上,它不完全符合上述条件,但是使用了一些JVM优化 避免匿名类的开销。 但是,深入研究这些JVM详细信息在这里可能会导致太远了。