-->

How does a method “reference to an instance method

2019-04-09 14:50发布

问题:

This question already has an answer here:

  • Instance Method Reference and Lambda Parameters 2 answers

The oracle Java 8 documentation defines 4 types of method references you can use instead of Lambda Expressions. What I am trying to understand is the kind of method reference described as: "Reference to an instance method of an arbitrary object of a particular type " which is written as ContainingType::methodName.

I am not sure if I am missing something, but to me it seems more like: "Reference to the first parameter of the abstract method of the Functional Interface, assuming it is of type ContainingType". I tried to come up with examples where this 'arbitrary object' is the second parameter, but of course it does not compile.

Is there an official reference how this object is resolved by the compiler? Am I correct in my understanding that:

  1. The arbitrary object has to be the 1st parameter of the abstract method of the functional interface.
  2. The signature of the method reference must be the same as that of the abstract method of the functional interface, without the first parameter.

So a functional interface with abstract method A method(B b, C c, D d) can only be passed instance method references x::methodImpl or B::methodImpl. There is no way I can pass C::methodImpl for example, where it would be an instance of class C with its signature A methodImpl(B b, D d).

Are there any other cases I am missing, which might be the reason why Oracle wrote this in such an ambiguous way?

回答1:

No, your understanding is correct. The documentation you linked implies (but does not adequately emphasize) that given a functional interface that expects args a1, a2, a3, ..., a method reference of this type is equivalent to a lambda that calls a1.namedMethod(a2, a3, ...).

Note that a concrete definition like this is required for consistency's sake - given the example on the linked documentation of a functional interface with two String arguments (String s1, String s2), how would you determine whether the behavior would be s1.doThing(s2) or s2.doThing(s1) otherwise?

You can find this specified precisely in the JLS:

If the compile-time declaration is an instance method, then the arguments to the method invocation expression (if any) are the second and subsequent formal parameters of the invocation method. Otherwise, the arguments to the method invocation expression are the formal parameters of the invocation method.