In Java 1.7.0_55, if I write this field declaration, I get a compilation error (\"incompatible types\"):
private final Map myMap =
This fails with your compiler error in Java 7, but it compiles successfully in Java 8. In short, the compiler's type inference did not catch the proper inferred types in Java 7, but the better type inference infers the proper types in Java 8.
This change was JEP (JDK Enhancement Proposal) 101 for Java 8.
Summary
Smoothly expand the scope of method type-inference to support (i) inference in method context and (ii) inference in chained calls.
Java 8 is able to infer types through multiple method calls with parameters and method call chaining. It can now determine from the left side of the assignment <String, Object>
through the call to Collections.synchronizedMap
to the diamond operator in the parameter to that call, new HashMap<>()
.
When a method is declared like this
public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
The genrecis are supplied by the parameters.
lets say i do this:
public <V> V returnV(V v);
Then i call it :
returnV("myString")
V is detrmind by myString.
when you give
new HashMap<>()
Then there are no generics so the compiler guesses you ment:
new HashMap<Object, Object>()
And so you get
private final Map<String,Object> myMap =
Collections.synchronizedMap(new HashMap<Object,Object>());
And that is and incompatible types error.
It's because you are trying to pass new HashMap<>()
to method of Collections
class. This is different than doing:
Map <String, Integer> map = new HashMap<>();
method you are using expects the Map of known type. Diamond syntax is just a sugar to standard syntax of declaring and initializing generic classes.