Reputation: 13
public class ExplicitTypeSpecification {
static void f(Map<Integer, String> map){}
public static void main(String[] args){
New c = new New();
f(c.map());
}
}
class New <K, V>{
Map<K, V> map(){
return new HashMap<K, V>();
}
}
This code compiles with no errors.
Then, we make some change in class New:
class New {
<K, V>Map<K, V> map(){
return new HashMap<K, V>();
}
}
We have parameterized just the method map()
, but not the whole class. But in this case a compile error occures at line f(c.map());
:
java: f(java.util.Map<java.lang.Integer,java.lang.String>) in
Generics.ExplicitTypeSpecification.ExplicitTypeSpecification cannot be applied to
(java.util.Map<java.lang.Object,java.lang.Object>)*
We can point explicit types f(c.<Integer, String>map());
but I'm interested in Why we get a compile error?.
In both cases method map()
returns Map<Object, Object>
object, but in first case we get just a warning of unchecked assignment.
Question: why at the second case we have more strict type checking?
What is the dirrefence between new HashMap()
and new HashMap<Object, Object>()
? Answer for this problem solves it.
Upvotes: 1
Views: 263
Reputation: 2214
If you don't specify the type parameters, backwards compatibility with Java 1.4 will suppose that you want "Object". Also, you will get a warning about this.
So your function is equivalent to:
public static void main(String[] args){
New c = new New();
f(c.<Object, Object>map());
}
And then you get an error saying that you are trying to use the value Map<Object, Object>
where a parameter Map<Integer, String>
is expected.
Note: Map<Integer, String>
is not a subtype of Map<Object, Object>
.
Upvotes: 0
Reputation: 16364
In the first case, you are using the raw type New
(rather than New<Integer, String>
) so all generic type-checking is disabled. This works as a compatibility mode for old (Java 1.4) code.
Upvotes: 2