举个例子:
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
}
}
为什么变量accumulator
是一个BiConsumer
,需要一个函数接受2个参数,可以用MyConsumer::accept
进行赋值code> 当该方法只接受单个参数时?
Java这种语言设计背后的原理是什么?如果有一个术语,它是什么?
最佳答案
MyConsumer::accept
是对 MyConsumer
类的实例方法的方法引用,该类具有 int
类型的单个参数。调用该方法的 MyConsumer
实例被视为方法引用的隐式参数。
因此:
accumulator = MyConsumer::accept;
相当于:
accumulator = (MyConsumer m,Integer i) -> m.accept(i);
given a targeted function type with n parameters, a set of potentially applicable methods is identified:
If the method reference expression has the form ReferenceType :: [TypeArguments] Identifier, the potentially applicable methods are the member methods of the type to search that have an appropriate name (given by Identifier), accessibility, arity (n or n-1), and type argument arity (derived from [TypeArguments]), as specified in §15.12.2.1.
Two different arities, n and n-1, are considered, to account for the possibility that this form refers to either a static method or an instance method.
(来自 15.13.1. Compile-Time Declaration of a Method Reference )
在您的例子中,目标函数类型是 BiConsumer
,它有 2 个参数。因此,MyConsumer
类中任何与名称 accept
匹配且具有 2 或 1 个参数的方法都会被考虑。
2个参数的静态方法和1个参数的实例方法都可以匹配目标函数类型。
关于lambda - 为什么允许为 BiConsumer 分配只接受单个参数的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48852471/