CodeQL 文档

没有 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

单击以在 CodeQL 存储库中查看查询

如果将这些类的实例存储在哈希数据结构中,则定义 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;
    }
}

在上述示例的修改中,类 PointhashCode 的实现是合适的,因为哈希码是由 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;
    }
}

参考资料

  • ©GitHub, Inc.
  • 条款
  • 隐私