...
Failure to follow this contract is a common source of bugs. Notably, immutable objects are exempt because they need not override the hashcode()
method.
Noncompliant Code Example
Even when the equals()
method conveys implements logical equivalence between classes of object instances, the default hashCode()
method returns distinct numbers as opposed to rather than returning the same values. Its value for all members of an equivalence class. However, its contract requires that it to return the same values for equal objectsvalue for all members of an equivalence class. This noncompliant code example stores a credit card number into a HashMap
and retrieves it. The expected retrieved value is Java
, however, null
is returned instead. The reason for this erroneous behavior is that the CreditCard
class overrides the equals()
method but fails to override the hashCode()
method is not overridden which means that a different bucket would be looked into than the one used to store the original . Consequently, the default hashCode()
method returns a different value for each object, even though the objects are logically equivalent; these differing values lead to examination of different hash buckets, which prevents the get()
method from finding the intended value.
Code Block | ||
---|---|---|
| ||
public final class CreditCard { private final int number; public CreditCard(int number) { this.number = (short) number; } public boolean equals(Object o) { if (o == this) { return true; } if (!(o instanceof CreditCard)) { return false; } CreditCard cc = (CreditCard)o; return cc.number == number; } public static void main(String[] args) { Map<CreditCard, String> m = new HashMap<CreditCard, String>(); m.put(new CreditCard(100), "Java"); // Assuming Integer.MAX_VALUE is the largest number for card System.out.println(m.get(new CreditCard(100))); } } |
...
Guideline | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
MET13-J | low | unlikely | high | P1 | L3 |
Automated Detection
TODOAutomated detection of classes that override only one of equals()
and hashcode()
is straightforward. Sound static determination that the implementations of equals()
and hashcode()
are mutually consistent is not feasible in the general case. Heuristic techniques may be useful for the latter issue.
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this guideline on the CERT website.
...