问题
Java provides me by <? extends class>
a way of filtering the java classes that you can use to
build in this case the new HashMap, for example:
I can do that:
Map<String,? extends Serializable> map1 = new HashMap<String,String>();
It is correct, because String implements Serializable, so the compiler let me do that.
But when i try to do it:
Map<String,GenericClass<? extends Serializable>> map2 = new HashMap<String, GenericClass<String>>();
Being the GenericClass as it:
public class GenericClass<T>
{
.
.
.
}
The compiler throw an error saying:
Type mismatch: cannot convert from HashMap<String,GenericClass<String>> to Map<String,GenericClass<? extends Serializable>>
I would like to know, what is happen?
Maybe the compiler cannot detect the extends class being part of a generic type.
回答1:
You would need to use the following:
Map<String, ? extends GenericClass<? extends Serializable>> map2 =
new HashMap<String, GenericClass<String>>();
Nested wildcards are much different from top-level wildcards - only the latter perform wildcard capture. As a result, HashMap<String, GenericClass<String>>
is considered inconvertible to Map<String, GenericClass<? extends Serializable>>
, because GenericClass<? extends Serializable>
is a concrete type argument (and because generics aren't covariant).
See this post for further information on nested wildcards: Multiple wildcards on a generic methods makes Java compiler (and me!) very confused
回答2:
Map<String,? extends Serializable> map1 = new HashMap<String,String>();
map1
contains an unbounded V
that only requires an unknown of Serializable
's. Hence it cannot find a generified object to bound this to, except for null
.
Map<String,GenericClass<? extends Serializable>> map2 = new HashMap<String, GenericClass<String>>();
The map2
is bounded by a type K
(in this case String
) and V
(Class<? exends Serializable
). That's how the Java compiler sees the bounds.
In essence, you cannot put
anything in map1
except a null as you will only see map1.put(String key, null value) //Compiler is asking WTF here
.
Whereas, map2
will, essentially "render" as map2.put(String key, Class<? extends Serializable> value); //Much better...
.
Because of the bound V
in map2
, the signature must be the same in its declaration.
来源:https://stackoverflow.com/questions/17723199/issue-with-declaration-of-mapstring-class-extends-serializable