为什么允许BiConsumer分配仅接受单个参数的函数?

sup*_*sky 6 lambda java-8

说出以下示例:

public class MyConsumer {
    public void accept(int i) {}
    public static void biAccept(MyConsumer mc, int i) {}
}

public class BiConsumerDemo {

    public void accept(int i) { }
    public static void biAccept(MyConsumer mc, int i) { }

    private void testBiConsume() {
        BiConsumer<MyConsumer, Integer> accumulator = (x, y) -> {}; // no problem, method accepts 2 parameters
        accumulator = MyConsumer::accept; // accepts only one parameter and yet is treated as BiConsumer
        accumulator = MyConsumer::biAccept; // needed to be static
        accumulator = BiConsumerDemo::accept; // compilation error, only accepts single parameter
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么在该方法仅接受一个参数的情况下,可以为变量accumulator(该变量BiConsumer需要一个函数接受2个参数)进行分配MyConsumer::accept呢?

Java语言设计背后的原理是什么?如果有一个术语,那是什么?

Era*_*ran 7

MyConsumer::accept是对MyConsumer类的实例方法的方法引用,该类方法具有单个类型的参数intMyConsumer调用该方法的实例被视为方法引用的隐式参数。

因此:

accumulator = MyConsumer::accept;
Run Code Online (Sandbox Code Playgroud)

等效于:

accumulator = (MyConsumer m,Integer i) -> m.accept(i);
Run Code Online (Sandbox Code Playgroud)

给定具有n个参数的目标函数类型,将确定一组可能适用的方法:

  • 如果方法引用表达式的形式为ReferenceType :: [TypeArguments] Identifier,则可能适用的方法是具有适当名称(由Identifier赋予),可访问性,一致性(n或n-1)的要搜索类型的成员方法。,然后输入参数arity(源自[TypeArguments]),如§15.12.2.1中所指定。

    考虑了两个不同的域n和n-1,以说明这种形式引用静态方法还是实例方法的可能性

(摘自15.13.1。方法参考的编译时声明

在您的情况下,目标函数类型为BiConsumer,具有2个参数。因此,将考虑MyConsumer与名称匹配accept并且具有2或1个参数的类的任何方法。

具有2个参数的静态方法和具有1个参数的实例方法都可以与目标函数类型匹配。