|
SemmleCode Professional comes with a wide range of pre-packaged analyses, from architectural properties and metrics, to statement-level checks for likely bugs and violations of best practice.
Hashed value without hashCode definition
This query finds classes whose values are stored in a hashing data structure, and which define an equals method but no
hashCode method. The contract of the hashCode method requires that two objects that equals considers
equal should have the same hash code, which is likely to be violated by such classes.
Consider the following example class:
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;
}
}
This class defines an equals method that checks two Point objects for structural equality. For example, if we construct two objects
of this class with the same coordinate values
Point p = new Point(23, 42);
Point q = new Point(23, 42);
then p.equals(q) will
return true. However, class Point does not override the default implementation of method
hashCode, hence p.hashCode() and
q.hashCode() will not necessarily be equal.
This violates the contract of the hashCode method, hence objects of type Point should not be stored in hashing data structures.
How to Interpret the Query Results
The query flags any such class with a warning if it is used in what appears to be a hashing data structure, and also displays the list of generated warnings
in the result view.
How to Address the Query Results
Every class that implements a custom equals method should also provide an implementation of hashCode. A possible implementation for
Point is
public int hashCode() {
int hash = 7;
hash = 31*hash + x;
hash = 31*hash + y;
return hash;
}
Since the hash code is computed from exactly the same fields that are considered in the equals method, its contract is fulfilled. In the
example, the hash code for both p and q is 7482.
Source Code
References
|