Allocating a generic collection as a function parameter

I am a bit puzzled by Java (7) behavior:

Let's say I have a ctor for Foo

that takes a parameter Map<String,String>

as a parameter. The following code:

new Foo(ImmutableMap.of());

      

Throws an error Error:

java: no matching constructor found for Foo (com.google.common.collect.ImmutableMap) constructor Foo (java.util.Map) not applicable

Trying to use for Map<String, String>

clearly doesn't work, and the compiler complains that the types are not convertible. However, this works fine:

Map<String, String> map = ImmutableMap.of();
new Foo(map);

      

What the hell is going on here? Why does the compiler treat a local variable differently than a function parameter?

+3


source to share


3 answers


The Java compiler doesn't seem to be able to infer generic types from the constructor signature and falls back to an erasable type (equivalent Map<Object, Object>

.)

Using:



new Foo(ImmutableMap.<String, String> of());

      

+6


source


ImmutableMap.of()

in the method signature, it returns empty Map<Object,Object>

, which is passed in, and there is no constructor defined for this type.

But when you use Map<String, String> map = ImmutableMap.of();

, than it returns in a specially Map<String ,String>

clean safe way.



You should use it like this new Foo(ImmutableMap<String ,String>.of());

+4


source


Java 7 needs a local variable to correctly infer the return type of an Immutable.of () object. In Java 8, they have improved this. See "Improved Type Inference" here: http://docs.oracle.com/javase/8/docs/technotes/guides/language/enhancements.html

+4


source







All Articles