java - 我试过转发一个方法给super,但是偶尔不行。为什么?

标签 java

这是有问题的代码,针对此示例进行了简化:

/** 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);
  }
}

You need to be careful when passing to super that you fully understand what the super method does. In this case, the contract for Hashtable.put is that it will record a mapping between the key and the value in the table. However, if the hashtable gets too full, then Hashtable.put will allocate a larger array for the table, copy all the old objects over, and then recursively re-call table.put(key, value). Now, because Java resolves methods based on the runtime type of the target, in our example this recursive call within the code for Hashtable will go to HashtableWithPlurals.put(key, value), and the net result is that occasionally (when the size of the table overflows at just the wrong time), you will get an entry for "dogss" as well as for "dogs" and "dog". Now, does it state anywhere in the documentation for put that doing this recursive call is a possibility? No. In cases like this, it sure helps to have source code access to the JDK.

解决方案?不要扩展 HashTable,而是使用一个包装类,它在内部存储一个 HashTable 并将必要的方法转发给它(不是 100% 完美的解决方案,但在大多数情况下它已经足够好并且没有这些问题)。好吧,或者非常仔细地查看源代码并确保您准确理解发生了什么......并编写大量测试(和一些模糊测试)

PS:在与认为 OOP 使一切变得如此简单和完全万无一失的人争论时,这几乎是我最喜欢的例子 - 仍然没有 Elixir ;)

PPS:考虑到这两个示例几乎相同 - 想告诉我们您从哪里得到的吗?只是好奇,因为这里似乎有人把 norvig 的帖子作为灵感;)

关于java - 我试过转发一个方法给super,但是偶尔不行。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6323923/

相关文章:

java - 从 Google Chrome 的开发者工具获取信息

java - 覆盖 HashMap 中的等于问题

java - 使用 Java 8 按任意间隔将 Double 分组到 Map

java - 图表需要多大才能触发斐波那契堆的最坏情况复杂性?

java - 从标签 <font color ="red"> 读取文本并通过控制台打印

java - Spring Boot SOAP Web 服务的 EndpointNotFound 异常

java - userDetailsS​​ervice org.springframework.beans.factory.UnsatisfiedDependencyException 错误

java - Wicket 口 6 : Including Javascript files to head with script tag

java - 不同 View 中具有相同 ID 的两个按钮

java - 具有部分任务排序的 ScheduledExecutorService