1

1)阅读HashMap.java的代码。在第 762 行,注释说子类覆盖它以改变 put 方法的行为。但是,函数void addEntry(int,K,V,int)是私有函数。它如何被子类覆盖?

             /**
  758        * Adds a new entry with the specified key, value and hash code to
  759        * the specified bucket.  It is the responsibility of this
  760        * method to resize the table if appropriate.
  761        *
  762        * Subclass overrides this to alter the behavior of put method.
  763        */
  764       void addEntry(int hash, K key, V value, int bucketIndex) {
  765           Entry<K,V> e = table[bucketIndex];
  766           table[bucketIndex] = new Entry<>(hash, key, value, e);
  767           if (size++ >= threshold)
  768               resize(2 * table.length);

2) 在第 746 行和第 753 行,recordAccessrecordRemoval这两个函数保持为空。那么子类如何覆盖这两个函数呢?

             static class Entry<K,V> implements Map.Entry<K,V> {
  688           final K key;
  689           V value;
  690           Entry<K,V> next;
  691           final int hash;

                ...

                 /**
  742            * This method is invoked whenever the value in an entry is
  743            * overwritten by an invocation of put(k,v) for a key k that's already
  744            * in the HashMap.
  745            */
  746           void recordAccess(HashMap<K,V> m) {
  747           }
  748   
  749           /**
  750            * This method is invoked whenever the entry is
  751            * removed from the table.
  752            */
  753           void recordRemoval(HashMap<K,V> m) {
  754           }
  755       }
4

1 回答 1

2

这些方法都不 private是。

未指定时的可访问性称为“包私有”。特别是,这些方法可以同一个包中的其他类覆盖。原因可能是 Java 作者希望确保他们可以随时更改/重命名/替换此方法而不会破坏任何应用程序。当您不确定 API 是否良好时,将这些部分保持为“包私有”是很有意义的,收集一些以这种方式扩展类的经验,一旦您确定 API 将保持这种方式,您以后仍然可以将它们公开。但是,您不能制作它们private,否则您自己的类也将不允许扩展它们!

要获得真正 private的方法,您应该使用关键字private。没有任何规范,默认就是所谓的“包私有”,对于公共接口,当没有指定时它甚至是公共的。

如果您使用的是 Eclipse,请在方法名称上尝试 Ctrl+T 以查看是否有任何类覆盖它们。

于 2012-12-24T20:44:14.553 回答