考虑一下我的自定义扩展哈希图:
public class CustomHashMap extends HashMap<String, Object> {
...
}
为什么CustomHashMap是HashMap的子级,但为什么此方法不起作用?
Map<String, HashMap<String, Object>> customs = new LinkedHashMap<String, CustomHashMap>();
但这有效:
Map<String, HashMap<String, Object>> customs = new LinkedHashMap();
并且在将CustomHashMap添加(放入)
customs
映射时也可以使用。customs.put("test", new CustomHashMap());
似乎很奇怪,未在初始化时指定泛型就可以使用,但事实并非如此。
最佳答案
使用泛型时,应始终牢记类型擦除。在运行时,类型Map
的objct不再知道其类型参数。结果:LinkedHashMap<String, CustomHashMap>
不是Map<String, HashMap<String, Object>>
的子类型。
如果要关联某事子类型,则必须通过以下方式进行:
Map<String, ? extends HashMap<String, Object>> customs = new LinkedHashMap<String, CustomHashMap>();
这称为上限通配符,在这种情况下完全存在:获得子类型关系。有关更多信息,请引用Java tutorial about generics。
根据评论的其他信息:
上限版本在使用海关 map 方面有一个缺点。您不能再将实例放到该 map 中。唯一允许的值为
null
。原因是,您可以拥有另一个扩展Map<String, HashMap>
的类,然后尝试将其实例放入您的海关 map 中。但这是一个问题,因为变量custom指向使用CustomHashMap
参数化的 map 。使用有界通配符时,应始终提醒PECS。 PECS代表“生产者扩展,消费者 super ”。这对于方法参数很有值(value)。如果编写的方法仅需要从此类映射中读取值,则可以将参数键入为
Map<String, ? extends Map<String, Object>>
。这称为生产者。如果您只需要写入该 map ,请使用关键字super。如果同时需要读和写,那么您将无法执行任何一项操作。关于java - 继承不适用于作为通用类型传递的继承,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19976587/