Why class/object name must be explicitly specified for method references?

Solution 1:

I can’t speak for the Java developers but there are some things to consider:

There are certain kind of method references:

  1. Reference to a static method, e.g. ContainingClass::staticMethodName
  2. Reference to an instance method of a particular object, e.g. containingObject::instanceMethodName
  3. Reference to an instance method of an arbitrary object of a particular type, e.g. ContainingType::methodName
  4. Reference to a constructor, e.g. ClassName::new

The compiler already has to do some work to disambiguate the forms 1 and 3 and sometimes it fails. If the form ::methodName was allowed, the compiler had to disambiguate between three different forms as it could be any of the three forms from 1 to 3.

That said, allowing the form ::methodName to short-cut any of the form 1 to 3 still wouldn’t imply that it is equivalent to the form methodName(…) as the expression simpleName ( argopt ) may refer to

  • an instance method in the scope of the current class or its superclasses and interfaces
  • a static method in the scope of the current class or its superclasses
  • an instance method in the scope of an outer class or its superclasses and interfaces
  • a static method in the scope of an outer class or its superclasses
  • a static method declared via import static

So saying something like “::name should be allowed to refer to any method name(…) may refer to” implies to combine the possibilities of these two listings and you should think twice before making a wish.


As a final note, you still have the option of writing a lambda expression like args -> name(args) which implies resolving name like a simple method invocation of the form name(args) while at the same time solving the ambiguity problem as it eliminates the option 3 of the method reference kinds, unless you write explicitly (arg1, otherargs) -> arg1.name(otherargs).