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

时间:2018-02-18 13:58:26

标签: 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
    }
}

为什么变量accumulatorBiConsumer,需要函数接受2个参数?当该方法只接受单个参数时,可以使用MyConsumer::accept进行分配?

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

1 个答案:

答案 0 :(得分:4)

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

因此:

accumulator = MyConsumer::accept;

相当于:

accumulator = (MyConsumer m,Integer i) -> m.accept(i);
  

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

     
      
  • 如果方法引用表达式的格式为ReferenceType :: [TypeArguments] Identifier,则可能适用的方法是要搜索的类型的成员方法,这些方法具有适当的名称(由Identifier给出),accessibility,arity < strong>(n或n-1),类型参数arity(派生自[TypeArguments]),如§15.12.2.1中所述。

         

    考虑两种不同的元素n和n-1,以说明此形式可能是静态方法还是实例方法

  •   

(来自15.13.1. Compile-Time Declaration of a Method Reference

在您的情况下,目标函数类型为BiConsumer,其中包含2个参数。因此,MyConsumer类匹配名称accept且具有2或1个参数的任何方法都会被考虑。

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