Java 8: ссылка метода на статический метод нестатическим способом

Я изучаю новый Stream API для экзамена OCP и обнаружил что-то, чего я не совсем понимаю. Вот мой код:

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;
}

Здесь у меня есть статический метод сравнения и нестатический метод сравнения. Если я вызываю метод сравнения из нестатического метода, я получаю предупреждение компилятора:

Метод сравнения (Integer, Integer) из типа TestStream должен быть доступен статическим способом.

Если вместо этого я использую ссылку на метод в том же методе в моем потоке, это предупреждение компилятора становится ошибкой компилятора с тем же сообщением.

Я знаю, почему я получаю предупреждение, но я не понимаю, почему это предупреждение становится ошибкой компиляции, если я использую ссылку на метод. В Интернете я тоже ничего не нашел. Может кто-нибудь объяснить это мне?

2 ответа

Решение

Доступ к статическому методу через ссылку до сегодняшнего дня считался ошибкой проектирования AFAIK. Вы даже можете сделать:

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

И это будет работать нормально (хотя с предупреждением).

Когда функции java-8 были разработаны, это было исправлено, поэтому единственный способ получить доступ к статическому методу (для ссылки на метод) - через сам класс:

YourClass::compare

Я знаю, почему я получаю предупреждение, но я не понимаю, почему это предупреждение становится ошибкой компиляции, если я ссылаюсь на метод. В Интернете я тоже ничего не нашел. Может кто-нибудь объяснить это мне?

В обоих случаях это должна была быть ошибка компиляции, но более ранние версии Java допускали ее, потому что разработчики языка не знали этого лучше, и теперь для дальнейшей совместимости уже слишком поздно ее менять.

Тем не менее, ссылки на методы являются вновь созданным синтаксисом языка. Когда вы используете конструкцию <object instance>::<method name>тогда, по определению, метод, на который вы пытаетесь ссылаться, не может быть статическим методом, поскольку вы обращаетесь к нему, указав, к какому экземпляру объекта вы хотите применить его, что статический метод не может сделать.

Делая это правильно в этот раз и отвергая недопустимые конструкции, которые пытаются получить доступ к статическим материалам через экземпляр, не нарушается какой-либо существующий синтаксис языка, который кто-то мог где-то использовать, хотя и неразумно. Таким образом, они сделали это правильно на этот раз. Не делайте недопустимых вещей, компилятор должен их отклонить, и в этом случае это произойдет.

Это также усложнило бы вывод параметров в случае перегруженных методов, некоторые статические и некоторые нестатические. Но это был бы не первый адский вывод, с которым им пришлось бы обходиться.

Другие вопросы по тегам