Why does the class / object name have to be explicitly specified for method references?

When I want to refer to a method in the current scope, I still need to specify the class name (for static methods) or this

before the ::

operator. For example, I need to write:

import java.util.stream.Stream;

public class StreamTest {
    public static int trimmedLength(String s) {
        return s.trim().length();
    }

    public static void main(String[] args) {
        System.out.println(Stream.of("  aaa  ", "  bb ", " c ")
                .mapToInt(StreamTest::trimmedLength).sum());
    }
}

      

This is not a big problem for this

, but sometimes looks overkill for static methods as the class name can be quite long. It would be nice if the compiler would let me just write ::trimmedLength

:

public static void main(String[] args) {
    System.out.println(Stream.of("  aaa  ", "  bb ", " c ")
            .mapToInt(::trimmedLength).sum());
}

      

However, the Java-8 compiler does not allow this. To me it seems like it would be quite consistent if the class / object name were resolved in the same way as for a normal method call. This will also support static imports for method references, which can also be useful in some cases.

So the question is, why hasn't this or similar syntax been implemented in Java 8? Are there any problems with this syntax? Or was it just not considered at all?

+3


source to share


1 answer


I can't speak for Java developers, but there are some things to consider:

There are certain kinds of method references :

  • A reference to a static method, eg. ContainingClass::staticMethodName

  • A reference to an instance method of a particular object, eg. containingObject::instanceMethodName

  • A reference to an instance method of an arbitrary object of a specific type, eg. ContainingType::methodName

  • Link to constructor eg. ClassName::new

The compiler has to do some disambiguation of Forms 1 and 3 already, and sometimes it fails . If the form was ::methodName

allowed, the compiler had to clear up the ambiguity between the three different forms, since it could be any of the three forms 1 through 3.

However, for a form to ::methodName

abbreviate any of the forms 1 through 3 would still not mean that it is equivalent to the form methodName(…)

, since the expression can refer tosimpleName ( argopt )



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

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

    method in scope of the outer class or its superclasses
  • a static

    , declared viaimport static

So to say something like " ::name

should be allowed to refer to any method that name(…)

can refer to" means to combine the capabilities of the two lists, and you should think twice before you wish.


As a final note, you still have the option to write a lambda type expression args -> name(args)

that implies resolution name

as a simple invocation of a form method name(args)

, while at the same time solving the ambiguity problem as it eliminates option 3 of the method's reference types unless you explicitly write (arg1, otherargs) -> arg1.name(otherargs)

.

+6


source







All Articles