Suppose we have the following code:
public class Main {
public static void main(String[] args) {
}
private static <K, V extends Comparable<V>> Map<K, V> sorted(Map<K, V> map) {
return map.entrySet()
.stream()
.sorted(Comparator.comparing(Entry::getValue))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
}
}
A fairly simple snippet - we take a map and return another map that represents the same map, but sorted according to its values.
Let's change the functionality a little bit - instead of returning something based on an argument, let's introduce and work on a static
object:
public class Main {
public static void main(String[] args) {
}
private static Map<Integer, String> map = new HashMap<>();
private static <K, V extends Comparable<V>> Map<K, V> sorted() {
return map.entrySet()
.stream()
.sorted(Comparator.comparing(Entry::getValue))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
}
}
Note that the only thing we changed was getting rid of the argument and, instead, working with a static
field. One may wonder why then introduce the generics K
and V
at all - after all they will always be Integer
and String
, respectively. But wouldn't that mean that Java can easily deduce those arguments? Why exactly does it fail with an error of:
Error:(16, 25) java: incompatible types: inference variable K has incompatible bounds equality constraints: K,K lower bounds: java.lang.Integer
I have seen some questions regarding similar error messages, but I couldn't get any information from there. Why exactly does this fail? It's maybe worth to mention that while the compiler produces the above error, when using IntelliJ IDEA, the Entry::getKey
and Entry::getValue
method references are highlighed in red and, when hovered over, the following message gets displayed:
Non-static method cannot be referenced from a static context.
Which is weird, since I see nothing alike in the actual error message from javac
.