决定不使用完全泛型的get方法的原因是什么 在java.util接口中。地图< K、V >。
为了澄清问题,该方法的签名为
V get(对象键)
而不是
V get(K键)
我想知道为什么(同样的事情为remove, containsKey, containsValue)。
决定不使用完全泛型的get方法的原因是什么 在java.util接口中。地图< K、V >。
为了澄清问题,该方法的签名为
V get(对象键)
而不是
V get(K键)
我想知道为什么(同样的事情为remove, containsKey, containsValue)。
当前回答
向后兼容,我想。Map(或HashMap)仍然需要支持get(Object)。
其他回答
还有一个更重要的原因,它在技术上不能做到,因为它破坏了地图。
Java has polymorphic generic construction like <? extends SomeClass>. Marked such reference can point to type signed with <AnySubclassOfSomeClass>. But polymorphic generic makes that reference readonly. The compiler allows you to use generic types only as returning type of method (like simple getters), but blocks using of methods where generic type is argument (like ordinary setters). It means if you write Map<? extends KeyType, ValueType>, the compiler does not allow you to call method get(<? extends KeyType>), and the map will be useless. The only solution is to make this method not generic: get(Object).
向后兼容,我想。Map(或HashMap)仍然需要支持get(Object)。
兼容性。
在泛型可用之前,只有get(Object o)。
如果他们改变了这个方法来获得(<K> o),这可能会迫使java用户进行大量的代码维护,只是为了让正常的代码重新编译。
他们可以引入一个额外的方法,比如get_checked(<K> o),并弃用旧的get()方法,这样就有了一个更温和的过渡路径。但出于某种原因,这并没有做到。(我们现在所处的情况是,需要安装findBugs之类的工具来检查get()参数和map的声明键类型<K>之间的类型兼容性。)
我认为与.equals()的语义相关的参数是虚假的。(从技术上讲,他们是正确的,但我仍然认为他们是假的。如果o1和o2没有任何共同的超类,任何头脑正常的设计师都不会让o1.equals(o2)为真。)
我们正在做大的重构,我们错过了这个强类型的get(),以检查我们是否错过了旧类型的get()。
但是我发现了编译时间检查的变通/丑陋的技巧:创建Map接口,强类型get, containsKey, remove…然后放到java中。您的项目的Util包。
你只调用get()就会得到编译错误,…对于错误的类型,其他的编译器似乎都可以(至少在eclipse kepler内部)。
不要忘记在检查构建后删除此接口,因为这不是您在运行时想要的。
合同的表述如下:
更正式地说,如果这个映射包含 从键k到值v的映射 (key==null ?)k = =零: key。equals(k)),然后这个方法 返回v;否则返回null。 (最多可以有一个这样的 映射)。
(我的重点)
因此,成功的键查找取决于输入键对等式方法的实现。它不一定依赖于k的类。