This code compiles in Java 8 but fails to compile in Java 7:
class Map<K,V> { static <K,V> Map<K,V> empty() {return null;} Map<K,V> put(K k, V v) {return null;} V get(K k) {return null;} } class A { static void f(Map<Integer,String> m){} public static void main(String[] args) { f(Map.empty()); } } It doesn't infer the concrete type of the Map being returned from Map.empty():
$ javac7 A.java A.java:10: error: method f in class A cannot be applied to given types; f(Map.empty()); ^ required: Map<Integer,String> found: Map<Object,Object> reason: actual argument Map<Object,Object> cannot be converted to Map<Integer,String> by method invocation conversion 1 error It compiles if you change the f call to f(Map.<Integer,String>empty());. In Java 8, it works without having to resort to this.
But if you change the f call to f(Map.empty().put(1,"A").put(2,"B"));, it fails to compile once again, on both Java 7 and 8. Why?
$ $javac7 A.java A.java:10: error: method f in class A cannot be applied to given types; f(Map.empty().put(1,"A").put(2,"B")); ^ required: Map<Integer,String> found: Map<Object,Object> reason: actual argument Map<Object,Object> cannot be converted to Map<Integer,String> by method invocation conversion 1 error $ $javac8 A.java A.java:10: error: incompatible types: Map<Object,Object> cannot be converted to Map<Integer,String> f(Map.empty().put(1,"A").put(2,"B")); ^ Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output 1 error $ $javac8 -Xdiags:verbose A.java A.java:10: error: method f in class A cannot be applied to given types; f(Map.empty().put(1,"A").put(2,"B")); ^ required: Map<Integer,String> found: Map<Object,Object> reason: argument mismatch; Map<Object,Object> cannot be converted to Map<Integer,String> 1 error
static Map empty() {return null;}, Its not like your adding any modifiers using the generics anyway.