Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
546 views
in Technique[技术] by (71.8m points)

lambda - Why is BiConsumer allowed to be assigned with a function that only accepts a single parameter?

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

MyConsumer::accept is a method reference to an instance method of MyConsumer class that has a single argument of type int. The MyConsumer instance on which the method is called is considered an implicit argument of the method reference.

Therefore:

accumulator = MyConsumer::accept;

is equivalent to:

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.

(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 the MyConsumer class matching the name accept 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...