Non méthode statique ne peut pas être référencé à partir d'un contexte statique en java 8 flux
J'ai été jouer avec des exemples de http://www.concretepage.com/java/jdk-8/java-8-unaryoperator-binaryoperator-example.
Ce que je trouve vraiment déroutant, c'est que lorsque j'ai malencontreusement mis un mauvais type dans l'un des génériques lors de la formation des Collectionneurs, un compilateur java donne moi un message trompeur:
Non méthode statique ne peut pas être référencé à partir d'un contexte statique
Mon erreur n'a rien à voir avec statique vs instance de contexte dans la réalité:
Map<String, Map<Integer, Integer>> mapOfStudents = list.stream().collect(Collectors.groupingBy(Student::getClassName,
Collectors.toMap(Student::getName, Student::getAge)));
Mon erreur est dans le générique de type de retour. Quand j'ai corriger et mettre:
Map<String, Map<String, Integer>> mapOfStudents
tout va revenir à la normale.
Quelqu'un peut m'expliquer la raison derrière une telle confusion message d'erreur? Je suis sûr que les est une bonne idée, mais je n'arrive pas à saisir.
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)
- Je reçois un message bien différent avec
javac
(beaucoup plus clair). Bien que j'ai eu de même de mauvais messages d'erreur dans Eclipse lors de l'utilisation de la méthode références/lambdas. - Veuillez fournir la bonne marque et la version du compilateur java, que l'inférence de type est l'une des choses qui a été changer assez fréquemment.
- Voir modification de l'article pour plus de détails. Je suis à court d'Intellij Idea 2016.3
- C'est peut-être à la recherche pour un non-statique getName qui renvoie un Entier, mais le compilateur sauts hors de la recherche, comme seulement une méthode statique serait admissible.
- Mais je ne parle pas de "il". Compilateur Java doit être assez intelligent pour comprendre ce qu'est une référence à une méthode d'un objet arbitraire.
- Remarque le message semblable, ici.
- pouvez-vous donner un exemple pour un mauvais message dans Eclipse? Pour cet exemple, Eclipse (à la tête) dit: "incompatibilité de Type: impossible de convertir de Map<String,Map<String,Integer>> pour Map<String,Map<Integer,Integer>>", ce qui est très bon pour moi.
- Rien que je puisse reproduire un pour le moment. J'ai essayé de la question du code, et il semble que vous ne pouvez pas utiliser quick-fix pour y ajouter le manque de méthodes dans
Student
lors de l'utilisation de la méthode de référence (une fonctionnalité que j'utilise tout le temps). Qui pourrait en fait être le désagrément que j'ai été de me souvenir. - Je me souviens avoir vu de semblables trompeuse des messages d'erreur dans le passé, mais je ne peux pas le reproduire avec la question de l'exemple. En général, la réponse est que le compilateur de développement de l'est lors de la compilation de code correct correctement, pas à l'analyse de la cause de l'erreur. Parfois, c'est vraiment impressionnant ce qu'une petite erreur comme un seul égaré caractère (par exemple, une virgule ou un support) peut causer. Correctement analyser le problème de sciemment un faux code source pourrait exiger un programme totalement différent...
- en effet, la cjce se comporte beaucoup mieux ici, excellent travail!
Vous devez vous connecter pour publier un commentaire.
D'abord, il convient de noter, que le message est émis non pas par un compilateur java (javac), mais par IntelliJ IDEA. Vous pouvez voir javac messages dans les Messages "construction" de la fenêtre lorsque vous lancez un processus de construction. Ce que vous voyez dans la fenêtre d'édition des messages générés par l'IDÉE elle-même et ils diffèrent.
Le message d'erreur est trompeur en raison de la mise en œuvre de la méthode référence de la résolution dans IntelliJ IDEA. Il estime non-statique méthode de référence pour être résolus que si le nombre de correspondants SAM (seule méthode abstraite) des arguments est égal au nombre d'arguments de méthode plus un et le premier SAM type d'argument est compatible avec la méthode contenant la classe. Voir la mise en œuvre (également
isSecondSearchPossible
méthode ci-dessus, certaines magiques supplémentaires est effectuée pour les varargs méthodes).Il fonctionne correctement si votre programme ne comporte pas d'erreurs. Toutefois, si vous avez un mauvais type, les arguments génériques de la
Function
passé danstoMap
ne peut être remplacé, de sorte qu'il resteFunction<T, R>
, et sonapply
méthode premier argument est tout simplementT
qui ne correspond pas au typeStudent
. Ainsi, dits de "seconde recherche" échec de l'IDÉE et pense que la méthode est référencé à partir de contexte statique. Tout à la fois statiques et non statiques contexte ne sont pas applicables ici, non contexte statique correspond à votre méthode mieux, au moins selon le nombre d'arguments quegetName()
méthode reçoit pas d'arguments. D'autre part, l'IDÉE est la logique de "en cas de non-statique contexte n'est pas le cas, c'est un contexte statique", d'où le message d'erreur.Je ne considère pas cela comme un bug, ou au moins comme un problème d'utilisabilité. Je viens de connecté, il ici basé sur question similaire. J'espère que nous allons y remédier.
Disclaimer: je suis IntelliJ IDEA développeur.
Mise à jour: fixe dans l'IDÉE 2017.2.
javac
c'est un bug.