0

Given snippet:

Map map1 = new HashMap<>();
map1.entrySet().stream().forEach(entry -> {
    System.out.println(entry.getKey() + ":" + entry.getValue());
});

Without declaring generic types I get a compilation errors generally saying that entry in forEach is an Object type and not a Map.Entry.

If I add generics (either Object or ?), it compiles just fine:

Map<Object,Object> map2 = new HashMap<>();
map2.entrySet().stream().forEach(entry -> {
    System.out.println(entry.getKey() + ":" + entry.getValue());
});

Map<?,?> map3 = new HashMap<>();
map3.entrySet().stream().forEach(entry -> {
    System.out.println(entry.getKey() + ":" + entry.getValue());
});

Same compilation error when calling other Stream's API methods like filter, map, ...

Why missing generics makes compilation errors?

zolv
  • 1,720
  • 2
  • 19
  • 36
  • 3
    [What is a raw type and why shouldn't we use it](https://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it). – Oleksandr Pyrohov Jun 19 '19 at 09:34
  • I know about raw types. But generally my question is why compiler assumes that `entrySet()` returns `Set`, but `entrySet` method's is declared like this: `Set> entrySet();` which clearly states that it is a `Set>` and only typename of key and value are raw type. – zolv Jun 19 '19 at 09:41
  • 4
    The linked question contains the answer: *The type of a constructor, instance method, or non-static field of a raw type `C` that is not inherited from its superclasses or superinterfaces is the raw type that corresponds to the erasure of its type in the generic declaration corresponding to `C`*. In short, when you use a raw `Map`, the compiler erases all generic type information from the `Map` class. – Oleksandr Pyrohov Jun 19 '19 at 09:55

0 Answers0