2013-07-24 40 views
0

我正在閱讀Hashtable的代碼,並且我瞭解到Hashtable的鍵和值都不能爲null,但它的equals方法測試值爲null的情況。爲什麼Hashtable的equals方法測試值爲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; 
} 
+0

它可能是未來的目的,他們可以擴展功能。但是根據良好的編程指南,您總是需要檢查NPE – Reddy

+1

不要指望標準庫的代碼是完美的 - 它可能只是寫它的人沒有考慮它。 – Jesper

+0

爲什麼要讀一個類的代碼,它的使用已經被阻止了將近十年____? – fge

回答

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; 
} 

正如你所看到的,我們總是檢查null。這不是強制性的,而是一個很好的編程習慣。我知道在Hashtable的情況下它是沒有意義的,但正如我之前提到的,開發人員必須添加此檢查以保持統一模式。

更新:正如蒂姆建議Since Hashtable is subclassable, it is possible for a subclass to try to support null keys or values。所以做一個空檢查是安全的。

+1

由於Hashtable是可子類化的,所以子類可能會嘗試支持空鍵或值(或意外提供它們) - 因此檢查該情況是很理智的。 –

+0

好點@TimBoudreau。我同意。更新我的答案以結合您的觀點。 –

相關問題