没有 hashCode 定义的哈希值¶
ID: java/hashing-without-hashcode
Kind: problem
Security severity:
Severity: error
Precision: very-high
Tags:
- reliability
- correctness
Query suites:
- java-security-and-quality.qls
如果将这些类的实例存储在哈希数据结构中,则定义 equals
方法但没有 hashCode
方法的类可能会导致意外结果。哈希数据结构预期哈希码满足以下契约:equals
认为相等的两个对象应具有相同的哈希码。此类类可能会违反此契约。
建议¶
实现自定义 equals
方法的每个类还应提供 hashCode
的实现。
示例¶
在以下示例中,类 Point
没有 hashCode
的实现。对具有相同坐标的两个不同的 Point
对象调用 hashCode
可能导致不同的哈希码。这将违反 hashCode
方法的契约,在这种情况下,不应将类型为 Point
的对象存储在哈希数据结构中。
class Point {
int x;
int y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
public boolean equals(Object o) {
if (!(o instanceof Point)) return false;
Point q = (Point)o;
return x == q.x && y == q.y;
}
}
在上述示例的修改中,类 Point
的 hashCode
的实现是合适的,因为哈希码是由 equals
方法中考虑的完全相同的字段计算的。因此,hashCode
方法的契约得以实现。
class Point {
int x;
int y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
public boolean equals(Object o) {
if (!(o instanceof Point)) return false;
Point q = (Point)o;
return x == q.x && y == q.y;
}
// Implement hashCode so that equivalent points (with the same values of x and y) have the
// same hash code
public int hashCode() {
int hash = 7;
hash = 31*hash + x;
hash = 31*hash + y;
return hash;
}
}
参考资料¶
J. Bloch,Effective Java(第二版),第 9 项。Addison-Wesley,2008 年。
Java API 规范:Object.equals,Object.hashCode。
IBM developerWorks:Java 理论与实践:哈希处理。