Java 为什么方法引用与参数数不同的函数接口兼容?

Java 为什么方法引用与参数数不同的函数接口兼容?,java,java-8,method-reference,functional-interface,Java,Java 8,Method Reference,Functional Interface,我理解,如果引用的方法使用与函数接口相同数量的arg并返回相同类型,那么可以使用方法引用来实现函数接口,但为什么在某些情况下,引用的方法与函数接口具有不同数量的arg,但仍然兼容 我有一个简单的双消费者,我尝试使用方法引用来实现它。我知道只要args的数量匹配,我也可以使用lambda表达式。我将显示代码以清楚地解释它 我有一个BiConsumer,我想实现它 Lambda表达式的实现方法是: BiConsumer b=(firstArg,secondArg)->firstArg.add(sec

我理解,如果引用的方法使用与函数接口相同数量的arg并返回相同类型,那么可以使用方法引用来实现函数接口,但为什么在某些情况下,引用的方法与函数接口具有不同数量的arg,但仍然兼容

我有一个简单的双消费者,我尝试使用方法引用来实现它。我知道只要args的数量匹配,我也可以使用lambda表达式。我将显示代码以清楚地解释它

我有一个
BiConsumer
,我想实现它

Lambda表达式的实现方法是:

BiConsumer b=(firstArg,secondArg)->firstArg.add(secondArg)因为它们都接受2个输入参数,所以没有问题

但是为什么
biconsumera=ArrayList::add是否也兼容?ArrayList上的
add
方法只接受1个输入参数,但函数接口需要2个


如有任何答复,将不胜感激。谢谢

第一个参数是要调用
add
的ArrayList

在这种情况下,

ArrayList::add
意味着

这是一个双消费者

方法引用表达式(§15.13)可能与功能接口类型
T
兼容,如果
T
的功能类型的arity为
n
,则当方法引用表达式以arity
n
的功能类型为目标时,至少存在一种可能适用的方法(§15.13.1),且以下情况之一属实:

  • 方法引用表达式的形式为
    ReferenceType::[TypeArguments]标识符
    ,并且至少有一个可能适用的方法是(i)静态的,支持arity
    n
    或(ii)非静态的,支持arity
    n-1
要使用的函数类型具有arity 2

void accept(T t, U u);

ArrayList::add
引用的方法具有arity 1,它不是静态的。它使它具有潜在的适用性。

第一个参数是要调用
add
on的ArrayList,因为它在引用中使用了列表本身。我忘记了它的具体名称,但您可以将这些引用解析为h是在第一个参数上调用的,或者只是在以后传入第一个参数。例如,
myInstance::foo(int)
MyClass::foo(MyClass,int)
都可以解析为适合
BiConsumer
@Progman,我知道这一点,但我认为它引用的是1 arg add(),因为另一个add(整数索引,字符串)接受一个整数和一个字符串,但我的双消费者没有定义任何Integer@khelwood是的,我通过查看我的lambda解决方案了解了它是如何工作的,但为什么允许它?引用方法不应该与函数接口具有相同的参数吗?是的,我通过查看我的lambda解决方案了解了它是如何工作的,但为什么允许吗?引用方法不应该与函数接口具有相同的参数吗?如果函数接口被定义为
BiConsumer
,那么我将方法引用传递给1参数方法,它显示编译器错误。它是一个实例方法,所以它必须具有的参数之一是调用它的实例。这将是impost如果您没有提供ArrayList,可以使用
ArrayList::add
。您的意思是,当编译器看到方法引用时,它知道这是一个实例方法,因此它将尝试将第一个参数应用为实例,然后通过将第二个参数传递给它来调用该方法?这看起来像是一种特定类型的方法引用w当方法是一个(或任何参数)上的实例方法时,“当编译器看到方法引用时,它知道这是一个实例方法,因此它将尝试将第一个参数作为实例应用”--是的,我认为第一个论点在这里被称为接收者。你是如何学习spring的?我正在尝试学习spring,但迄今为止失败了。我需要你的帮助。你能为我提供一些资源来学习它吗?我真的需要帮助。我想学习在spring@Andrew中创建一个网站Tobilko@Pie我是官方消息来源的支持者。我通常阅读他们的文档()。这对初学者和有经验的开发人员都有好处。谢谢。这正是我要找的。因此,即使算术不匹配,它也是完全有效的。
void accept(T t, U u);