简体   繁体   中英

Java 8: method reference to a static method in a non-static way

I'm studying the new Stream API for the OCP exam and I found something that I don't really understand. Here's my code:

void methodOne() {
    this.compare(1, 2); // This works fine.
    Stream.of(1,2,3)
        .sorted(this::compare); // Compilation error.
}

static Integer compare(Integer s1, Integer s2) {
    return 0;
}

Here I have a static method called compare and a non-static one called compare. If I call the compare method from the non-static method I get a compiler warning:

The method compare(Integer, Integer) from the type TestStream should be accessed in a static way

If I instead use a method reference to that same method in my stream, that compiler warning becomes a compiler error with the same message.

I know why I get the warning but I don't get why this warning becomes a compilation error if I use a method reference. I didn't find anything online either. Can someone explain it to me?

Accessing a static method via a reference was seen as a design error to this day AFAIK. You can even do:

YourClass c = null;
c.compare (...)

And that would work just fine (with a warning though).

When java-8 features where designed this was corrected, so the only way to access a static method (for a method reference) is via the class itself:

YourClass::compare

I know why I get the warning but I don't get why this warning becomes a compilation error if I a method reference. I didn't find anything online either. Can someone explain it to me?

It should have been a compilation error in both cases, but the earlier versions of Java tolerated it because the designers of the language didn't know better, and now for continued compatibility it is too late to change it.

However, method references are a newly constructed language syntax. When you're using the construction <object instance>::<method name> , then by definition the method you're trying to reference cannot be a static method since you're accessing it by specifying what object instance you want it applied to, which a static method is incapable to do.

Doing it right this time and rejecting invalid constructs that try to access static stuff through an instance, doesn't break any existing syntax of the language that may have been used somewhere by someone, albeit unwisely. So they did it right this time. Don't do invalid things, the compiler ought to reject them, and in that case it will.

It would also complicate parameters inference in case of overloaded methods, some static and some non-static. But it wouldn't be the first inference hell they would have to make do with.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM