Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Failure to follow this contract is a source of common bugs.

Noncompliant Code Example

Even when the equals method conveys logical equivalence between classes, the hashCode method returns distinct numbers as opposed to returning the same values, as expected by the contract. This noncompliant 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 hashCode method is not overridden which means that a different bucket would be looked into than was used to store the original value.

Code Block
bgColor#FFCCCC
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 m = new HashMap();
    m.put(new CreditCard(100), "Java");
    System.out.println(m.get(new CreditCard(100)));
  }
}

Compliant Solution

Wiki Markup
This compliant solution shows how {{hashCode}} can be overridden so that the same value is generated for an instance. The recipe to generate such a hash function is described in \[[Bloch 08|AA. Java References#Bloch 08]\] Item 9: Always override {{hashCode}} when you override {{equals}}.

Code Block
bgColor#ccccff
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 int hashCode() {
    int result = 7;
    result = 37*result + number;
    return result;
  }

  public static void main(String[] args) {
    Map m = new HashMap();
    m.put(new CreditCard(100), "Java");
    System.out.println(m.get(new CreditCard(100)));
  }
}

Risk Assessment

TODO

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

MET31-J

??

??

??

P??

L??

Automated Detection

TODO

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

References

Wiki Markup
\[[Bloch 08|AA. Java References#Bloch 08]\] Item 9: Always override {{hashCode}} when you override {{equals}}
\[[API 06|AA. Java References#API 06]\] [Class Object|http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Object.html]