api为什么Java Map<K,V>为get和remove方法使用非类型化参数?
我在代码中遇到了一个错误,我使用了错误的键从Java映射中获取了一些我认为是使用Java泛型强类型的东西。当查看Map Javadocs时,许多方法(包括get和remove)都将对象作为参数,而不是类型K(对于定义为Map的Map)。为什么会这样?这是一个很好的理由还是一个API设计缺陷
你可以在下面搜索框中键入要查询的问题!
我在代码中遇到了一个错误,我使用了错误的键从Java映射中获取了一些我认为是使用Java泛型强类型的东西。当查看Map Javadocs时,许多方法(包括get和remove)都将对象作为参数,而不是类型K(对于定义为Map的Map)。为什么会这样?这是一个很好的理由还是一个API设计缺陷
# 1 楼答案
因为如果传递给get方法的对象等于映射中存储的任何键,则映射将返回一个值。Equal并不意味着它们必须是相同的类型,而是键和传递对象的Equal方法以这样的方式实现,即不同的对象类型被相互识别为相等
当然,删除方法也是如此
有效代码示例,如果get方法只允许K类型的参数,则会中断(而不是编译):
# 2 楼答案
我认为这是为了向后兼容旧版本的地图界面。不幸的是,情况就是这样。不过,你是对的,如果选择正确的类型会更好
# 3 楼答案
这样做的目的是,如果类型参数是通配符,则仍然可以调用这些方法
若您有一个
Map<?, ?>
,Java将不允许您调用任何以泛型类型作为参数声明的方法。这可以防止您违反类型约束,例如,您不能使用错误的类型调用put(key, value)
如果
get()
被定义为get(K key)
而不是当前的get(Object key)
,那么它也会因为同样的规则而被排除。这将使通配符映射实际上无法使用理论上,这同样适用于
remove()
,因为删除对象也永远不会违反类型约束下面是一个如果
get
被声明为get(T key)
就不可能实现的代码示例:e1.getKey()
返回某个未知子类型K
(由m1
使用的子类型)的对象,但m2
使用了可能不同的K
子类型。如果Map.get()
被声明为get(K key)
,则不允许这种用法