2017-02-13 1 views
12

Я играл с примерами от http://www.concretepage.com/java/jdk-8/java-8-unaryoperator-binaryoperator-example.Нестатический метод не может ссылаться на статический контекст в java 8 потоках

Что я нахожу действительно заблуждение в том, что, когда я по ошибке поставил неправильный тип в один из дженериков при формировании Коллекторы, Java компилятор дает мне очень обманчивое сообщение:

Non-статический метод не может ссылаться из статический контекст

Моя ошибка не имеет ничего общего со статическим против контекста, например, в реальности:

Map<String, Map<Integer, Integer>> mapOfStudents = list.stream().collect(Collectors.groupingBy(Student::getClassName, 
      Collectors.toMap(Student::getName, Student::getAge))); 

Мой м istake имеет общий тип возврата. Когда я исправлю его и поставлю:

Map<String, Map<String, Integer>> mapOfStudents 

все возвращается в норму.

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

EDIT:

~$ java -version 
openjdk version "1.8.0_121" 
OpenJDK Runtime Environment (build 1.8.0_121-8u121-b13-0ubuntu1.16.04.2-b13) 
OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode) 
+0

Я получаю совсем другое сообщение с 'javac' (гораздо яснее).Хотя у меня были подобные сообщения об ошибках в Eclipse при использовании ссылок на методы/lambdas. –

+1

Просьба указать точный make и версию java-компилятора, поскольку вывод типа - это одна из вещей, которая менялась довольно часто. – biziclop

+0

Подробнее см. В разделе «Редактирование». Я запускаю Intellij Idea 2016.3 – yuranos87

ответ

18

Прежде всего, следует отметить, что сообщение выдается не Java компилятор (JAVAC), но IntelliJ IDEA. Вы можете видеть сообщения javac в окне «Построение сообщений» при запуске процесса сборки. То, что вы видите в окне редактора, - это сообщения, созданные самой IDEA, и они могут отличаться.

Сообщение об ошибке вводит в заблуждение из-за реализации эталонного разрешения метода в IntelliJ IDEA. Он считает, что ссылка на нестатические методы должна быть разрешена только в том случае, если число соответствующих аргументов SAM (одиночный абстрактный метод) равно числу аргументов метода плюс один и первый тип аргумента SAM совместим с методом, содержащим класс. См. the implementation (также метод isSecondSearchPossible выше, для методов varargs выполняется дополнительная магия).

Он работает правильно, если ваша программа не имеет ошибок. Однако, если у вас есть несоответствующий тип, общие аргументы Function, переданные в toMap, не могут быть заменены, поэтому он остается Function<T, R>, а первый аргумент метода apply - это просто T, который не соответствует типу Student. Таким образом, происходит так называемый «второй поиск», и IDEA считает, что метод ссылается на статический контекст. Хотя статический и нестатический контексты здесь не применимы, нестатический контекст лучше соответствует вашему методу, по крайней мере, в соответствии с количеством аргументов, поскольку метод getName() не принимает никаких аргументов. С другой стороны, логика IDEA - «если нестатический контекст не применим, то это статический контекст», следовательно, сообщение об ошибке.

Я считаю это ошибкой или, по крайней мере, проблемой удобства использования. Я только что зарегистрировал его here на основе similar question. Надеюсь, мы это исправим.

Отказ от ответственности: Я разработчик IntelliJ IDEA.

Обновление: исправлено в IDEA 2017.2.

+0

Если это не согласуется с 'javac', это ошибка. – EJP

+3

@EJP, он согласен с тем, что программа неверна, но сообщение об ошибке отличается. Спецификация языка Java указывает, что является правильной программой, но в ней точно не указано, как сообщения об ошибках должны искать неверные программы. Обратите внимание, что сообщения об ошибках в компиляторе Eclipse также различны, и в этом случае на самом деле даже лучше, чем сообщения javac, в том смысле, что вы можете легче определить фактическую ошибку. Вы считаете это ошибкой в ​​компиляторе Eclipse? :-) –

+0

Для меня «нестатические и статические ссылки» далеки от того, что «общие типы не совпадают». – lwpro2

Смежные вопросы