0

我正在阅读Hashtable的代码,我了解到Hashtable的key和value都不能为null,但是它的equals方法测试了value是否为null的情况。

public synchronized boolean equals(Object o) {
if (o == this)
    return true;
if (!(o instanceof Map))
    return false;
Map<K,V> t = (Map<K,V>) o;
if (t.size() != size())
    return false;

    try {
        Iterator<Map.Entry<K,V>> i = entrySet().iterator();
        while (i.hasNext()) {
            Map.Entry<K,V> e = i.next();
            K key = e.getKey();
            V value = e.getValue();
            if (value == null) { // Can Hashtable's value be null?
                if (!(t.get(key)==null && t.containsKey(key))) 
                    return false;
            } else {
                if (!value.equals(t.get(key)))
                    return false;
            }
        }
    } catch (ClassCastException unused)   {
        return false;
    } catch (NullPointerException unused) {
        return false;
    }

return true;
}
4

1 回答 1

1

这是一种贯穿始终以处理 NPE 的模式。考虑一个简单的类

public class HelloWorld {
    String data;
}

如果您生成 hashCode() 和 equals(),您将看到遵循此一般模式。在这种情况下

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    HelloWorld that = (HelloWorld) o;

    if (data != null ? !data.equals(that.data) : that.data != null) return false;

    return true;
}

@Override
public int hashCode() {
    return data != null ? data.hashCode() : 0;
}

如您所见,我们总是检查空值。这不是强制性的,而是一种良好的编程习惯。我知道在 Hashtable 的情况下这是没有意义的,但正如我之前提到的,开发人员必须添加此检查以保持统一的模式。

更新:正如蒂姆建议的那样Since Hashtable is subclassable, it is possible for a subclass to try to support null keys or values。所以进行空检查是安全的。

于 2013-07-24T08:50:45.133 回答