JDK-8182323 : Add Hashable interface and compiler checking for hashCode/equals contract
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.util:collections
  • Affected Version: 9
  • Priority: P4
  • Status: Closed
  • Resolution: Not an Issue
  • Submitted: 2017-06-13
  • Updated: 2017-06-30
  • Resolved: 2017-06-30
Related Reports
Relates :  
Relates :  
Relates :  
Description
A DESCRIPTION OF THE REQUEST :
If the compiler is (optionally) checking hashing in a given project/module/package, each class therein that is passed to code that contains (anywhere) a call to hashCode must have an explicit, non-inherited implementation of both equals() and hashCode() OR the explicit annotation @InheritHashEquals. Under this system, nobody can accidentally put un-hashable objects into HashMaps or HashSets or indeed any code that relies on hashing. The compiler can immediately warn the user instead of absorbing hours of their time searching for subtle collection bugs. The idea may need some work, but it's a nasty problem that even after 20+ years still needs to be addressed if at all possible.

JUSTIFICATION :
Just spent 3 hours this morning debugging a problem due to a missing but completely trivial hashCode/equals implementation. Ugh.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Compiler should (optionally) check hash/equals and warn.
ACTUAL -
Subtle collection failures.


Comments
FYI, the check in question (JDK-6563143) and its subsequent refinements (JDK-8009138, JDK-8008436) have been available since JDK 8.
30-06-2017

Using "javac -Xlint:overrides" will issue a warning if a class overrides equals() but doesn't override hashCode(). This should be sufficient to catch errors with fulfilling the hashCode/equals contract. If necessary, this warning can be suppressed with @SuppressWarnings("overrides") on the class where it was intended to override equals() but not hashCode(). Closing as Not an Issue.
30-06-2017