10

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?

Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
  • 2
    Did you look at the discussion about this syntax in the JCP? I bet there is plenty you can find about this and other ideas. –  May 15 '15 at 05:11
  • 5
    No, I did not. It would be nice if you point to exact messages/opinions regarding my question. – Tagir Valeev May 15 '15 at 05:32

1 Answers1

6

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

Community
  • 1
  • 1
Holger
  • 285,553
  • 42
  • 434
  • 765
  • Thank you for the detailed answer. I was hoping that Java developers will answer, but probably my question is not very interesting for them. – Tagir Valeev May 18 '15 at 15:29
  • 1
    @Holger after using method reference for last 3 months, I am also inclined to think in Tagir's way. It is hard to understand that the expected form of method reference was omitted just because compiler has to do bit more task. Instead, compiler could try it's best to resolve. It can always ask for disambiguation with full form, if it can not resolve. – Mrinal Sep 13 '15 at 17:51
  • 2
    @Mrinal K. Samanta: not only the compiler has to do the disambiguation. The human reader has to do it too. And having the wrong idea of the method target will cause more harm than having to type a few less letters can ever compensate. – Holger Sep 14 '15 at 08:25
  • 6
    For anyone looking, there was a reponse from @Brian Goetz here: http://stackoverflow.com/questions/31665393/thismethodreference-or-equivalent-in-static-init-block-in-java-8#comment51275586_31665393 – xdhmoore Nov 20 '15 at 18:14