Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

When I want to refer to the method in the current scope I still need to specify class name (for static methods) or this before :: 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());
    }
}

It's not so big problem for this, but sometimes look overcrowded for static methods as the class name can be quite long. It would be nice if compiler allowed me to write simply ::trimmedLength instead:

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

However Java-8 compiler doesn't allow this. For me it seems that it would be quite consistent if class/object name were resolved in the same manner as it's done for normal method call. This would also support static imports for method references which also can be useful in certain cases.

So the question is why such or similar syntax was not implemented in Java 8? Are there any problems which would arise with such syntax? Or it was not simply considered at all?

like image 774
Tagir Valeev Avatar asked May 15 '15 05:05

Tagir Valeev


People also ask

Why do we need method references in Java?

The method references can only be used to replace a single method of the lambda expression. A code is more clear and short if one uses a lambda expression rather than using an anonymous class and one can use method reference rather than using a single function lambda expression to achieve the same.

Why do we use method reference?

out::println); For the replacement of a single method only, method references are used. The code automatically turns short and becomes clearer when the user uses the lambda expression instead of using an anonymous class. Also, a user can use the method reference instead of using lambda expression for a single function.

Which symbol specifies method references in Java?

Method references: A primer. The lambda presents (s) as its formal parameter list and a code body whose System. out. println(s) expression prints s 's value to the standard output stream.

What is the difference between a method reference and a lambda expression?

Lambda expression is an anonymous method (method without a name) that has used to provide the inline implementation of a method defined by the functional interface while a method reference is similar to a lambda expression that refers a method without executing it.


1 Answers

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).

like image 70
Holger Avatar answered Sep 29 '22 04:09

Holger