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行中, recordAccess 和 recordRemoval 这两个函数保持为空。那么子类如何覆盖这两个函数呢?
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 }
答案 0 :(得分:2)
这些方法不 private
。
未指定时的可访问性称为“包私有”。特别是,这些方法可以被同一个包中的其他类覆盖。原因是可能,Java作者希望确保他们可以随时更改/重命名/替换此方法而不会破坏任何应用程序。当你不确定API是否合适时,保持这些部分“包私有”是很有意义的,收集一些以这种方式扩展类的经验,并且一旦你确定API将保持这种方式你以后还可以把它们公之于众。但是,你不能使它们private
,否则也不允许你自己的类扩展它们!
要获取 true private
方法,您应该使用关键字private
。没有任何规范,默认值是所谓的“包私有”,对于公共接口,它甚至在没有指定任何内容时是公共的。
如果您正在使用eclipse,请尝试按方法名称上的Ctrl + T查看是否有任何类覆盖它们。