Say, for the following example:
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
}
}
Why is that the variable accumulator
, which is a BiConsumer
that requires a function to accept 2 parameters, can be assigned with MyConsumer::accept
when that method only accepts only a single parameter?
What is the principle behind this language design in Java? If there's a term for it, what is it?
MyConsumer::accept
is a method reference to an instance method ofMyConsumer
class that has a single argument of typeint
. TheMyConsumer
instance on which the method is called is considered an implicit argument of the method reference.Therefore:
is equivalent to:
(from 15.13.1. Compile-Time Declaration of a Method Reference )
In your case the target function type is
BiConsumer
, which has 2 parameters. Therefore any methods of theMyConsumer
class matching the nameaccept
and having 2 or 1 parameters are considered.Both static methods having 2 parameters and instance methods having 1 parameter can match the target function type.