考虑一下我的自定义扩展哈希图:

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/

10-11 22:16
查看更多