Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-static method cannot be referenced from a static context in java 8 streams

I was playing around with examples from http://www.concretepage.com/java/jdk-8/java-8-unaryoperator-binaryoperator-example.

What I find really confusing is that when I mistakenly put a wrong type into one of generics when forming Collectors, java compiler gives me a very misleading message:

Non-static method cannot be referenced from a static context

My error has nothing to do with static vs instance context in reality:

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

My mistake is in generic return type. When I correct it and put:

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

everything goes back to normal.

Can someone explain the reason behind such a confusing error message? I'm sure the is a good one, but I fail to grasp it.

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) 
like image 818
yuranos Avatar asked Feb 13 '17 09:02

yuranos


People also ask

How do you fix non static method Cannot be referenced from a static context Java?

Therefore, this issue can be solved by addressing the variables with the object names. In short, we always need to create an object in order to refer to a non-static variable from a static context. Whenever a new instance is created, a new copy of all the non-static variables and methods are created.

Why non static variable Cannot be referenced from a static context in Java?

The error non static variable cannot be referenced from a static context in Java is mostly faced by the beginners at the time of compilation of Java program. The reason to occur this error is that they use a non-static member variable in the main() method.

What does non static method Cannot be referenced from a static context?

A non-static method is dependent on the object. It is recognized by the program once the object is created. But a static method can be called before the object creation. Hence you cannot make the reference.

Why non static variable Cannot be referenced from a static context?

Contrary to this, non-static variables and methods depend on class instances, as they store and manipulate data specific to individual objects. Therefore, non-static members cannot be accessed from a static context, i.e., there has to be a class instance that references these members.


1 Answers

First it should be noted, that the message is issued not by java compiler (javac), but by IntelliJ IDEA. You can see javac messages in "Messages Build" window when you actually launch a build process. What you see in editor window is messages generated by IDEA itself and they could differ.

The error message is misleading due to implementation of method reference resolution in IntelliJ IDEA. It considers non-static method reference to be resolved only if number of corresponding SAM (single abstract method) arguments equals to number of method arguments plus one and the first SAM argument type is compatible with method containing class. See the implementation (also isSecondSearchPossible method above, some additional magic is performed for varargs methods).

It works correctly if your program has no errors. However if you have a mismatched type, the generic arguments of the Function passed into toMap cannot be substituted, so it remains Function<T, R>, and its apply method first argument is simply T which does not correspond to the type Student. Thus so-called "second search" fails and IDEA thinks that the method is referenced from static context. While both static and non-static context are not applicable here, non-static context matches your method better, at least according to the number of arguments as getName() method receives no arguments. On the other hand, IDEA logic is "if non-static context is not applicable, then it's a static context", hence the error message.

I would consider this as a bug, or at least as a usability problem. I've just logged it here based on similar question. Hopefully we will fix it.

Disclaimer: I'm IntelliJ IDEA developer.

Update: fixed in IDEA 2017.2.

like image 82
Tagir Valeev Avatar answered Sep 26 '22 09:09

Tagir Valeev