Problem with map declaration <String, Class <? Extends Serializable >>

Java provides me with <? extends class> <? extends class> way to filter java classes that you can use to build a new HashMap in this case, for example:

I can do it:

 Map<String,? extends Serializable> map1 = new HashMap<String,String>(); 

This is correct because String implements Serializable, so the compiler allows me to do this.

But when I try to do this:

 Map<String,GenericClass<? extends Serializable>> map2 = new HashMap<String, GenericClass<String>>(); 

Being a GenericClass like this:

 public class GenericClass<T> { . . . } 

The compiler gives an error message:

 Type mismatch: cannot convert from HashMap<String,GenericClass<String>> to Map<String,GenericClass<? extends Serializable>> 

I would like to know what is going on?

Perhaps the compiler cannot detect that the extends class is part of a generic type.

+4
source share
2 answers

You will need to use the following:

 Map<String, ? extends GenericClass<? extends Serializable>> map2 = new HashMap<String, GenericClass<String>>(); 

Nested wildcards are very different from top-level wildcards — only the last ones perform group capture . As a result, HashMap<String, GenericClass<String>> is considered irreversible for Map<String, GenericClass<? extends Serializable>> Map<String, GenericClass<? extends Serializable>> because GenericClass<? extends Serializable> GenericClass<? extends Serializable> is an argument of a specific type (and because generics are not covariant ).

See this post for more information on nested wildcards: Multiple wildcards for common methods make the Java compiler (and me!) Very confusing

+2
source
 Map<String,? extends Serializable> map1 = new HashMap<String,String>(); 

map1 contains an unlimited V , which requires only an unknown Serializable value. Therefore, it cannot find the generic object associated with this except null .

 Map<String,GenericClass<? extends Serializable>> map2 = new HashMap<String, GenericClass<String>>(); 

map2 limited by type K (in this case String ) and V ( Class<? exends Serializable ). This is how the Java compiler sees boundaries.

Essentially, you cannot put anything in map1 other than zero, since you will only see map1.put(String key, null value) //Compiler is asking WTF here . Whereas map2 will essentially "map" as map2.put(String key, Class<? extends Serializable> value); //Much better... map2.put(String key, Class<? extends Serializable> value); //Much better...

Due to the restriction of V in map2 signature must be the same in its declaration.

+1
source

Source: https://habr.com/ru/post/1492077/


All Articles