问题描述
|
这是有问题的代码,此示例已简化:
/** A version of Hashtable that lets you do
* table.put(\"dog\",\"canine\");,and then have
* table.get(\"dogs\") return \"canine\". **/
public class HashtableWithPlurals extends Hashtable {
/** Make the table map both key and key + \"s\" to value. **/
public Object put(Object key,Object value) {
super.put(key + \"s\",value);
return super.put(key,value);
}
}
解决方法
哦,天哪,您覆盖了一个哈希表。是的,在这种情况下,文档并不是特别有用。
我只引用彼得·诺维格(Peter Norvig),因为他说的比我更好:
public class HashtableWithPlurals extends Hashtable {
/** Make the table map both key and key + \"s\" to value. **/
public Object put(Object key,Object value) {
super.put(key + \"s\",value);
return super.put(key,value);
}
}
传递给
超级,你完全了解什么
超级方法。在这种情况下,
Hashtable.put的合同是
它将记录之间的映射
键和表格中的值。
但是,如果哈希表太
已满,那么Hashtable.put将分配
该表的较大数组,请复制所有
老物件过去了,然后
递归调用table.put(key,
值)。现在,因为Java解决了
基于运行时类型的方法
目标,在我们的示例中
代码内的递归调用
哈希表将转到
HashtableWithPlurals.put(key,value),
最终结果是
偶尔(当
表在错误的地方溢出
时间),您将获得一个条目
\“ dogss \”以及\“ dogs \”和
\“狗\”。现在,它是否在
这样做的文档
这种递归调用是可能的吗?
否。在这种情况下,肯定有帮助
可以访问JDK的源代码。
解决方案?不要扩展HashTable,而是使用一个包装器类,该包装器类在内部存储HashTable并向其转发必要的方法(不是100%完美的解决方案,但在大多数情况下它已经足够好,并且没有那些问题) 。好吧,或者非常好地看一下源代码,并确保您完全了解正在发生的事情..并编写大量测试(和一些fuzztest)
PS:当与认为OOP使一切变得如此简单和完全安全的人们争论时,这几乎是我最喜欢的示例-仍然没有灵丹妙药;)
PPS:考虑到这两个示例几乎相同,请告诉我们您从哪里得到的?只是好奇,因为似乎有人在这里以norvig帖子为灵感;)
, 您是否应退还super.get(key);
?
编辑
现在,我更加仔细地看了一下,您的put
方法应该只是void
吗?为什么首先要返还ѭ5?