What are ways to keep hashCode/equals consistent with the business definition of the class?

后端 未结 6 2066
萌比男神i
萌比男神i 2021-02-01 19:12

Object javadocs and Josh Bloch tell us a great deal about how hashCode/equals should be implemented, and good IDEs will handle fields of various types correctly. Some discussio

相关标签:
6条回答
  • 2021-02-01 19:44

    You don't need to include every field in your hash code method. If you used more than one field in your hash code algorithm then the chances are it will remain good. The IDE-generated algorithms I've seen use a random (at the time of implementation, not at execution) prime constant value, so just make sure that classes that could end up in the same map or tree together (e.g. they implement the same interface) have different constant values. Unless, of course, you want equality at the interface level.

    I've never seen a hash code algorithm "go bad" - you're worrying a disproportionate amount about this.

    0 讨论(0)
  • 2021-02-01 19:52

    Sounds like what you're looking for is an addon or feature in an IDE that performs the analysis of the classes and generates warnings if the equals() and hashCode() methods do not reference all the relevant fields.

    This would basically move the reflection overhead to the IDE rather than let it have the cost during run-time.

    Unfortunately, I don't know of any addon that does this, though I'll certainly have a look.

    On the other hand, how would such an automated tool know which fields are relevant for business logic? You'd probably need to mark irrelevant fields with something like an annotation, otherwise you could find yourself with warnings you can't get rid of, but that you know are incorrect.

    Edit: This answer is not useful, so I'm just compiling here the really useful suggestions from better answers:

    • Project Lombok - Eclipse addon that also works with build tools to provide automatic generation of equals(), hashCode() and other boiler-plate code - since it's generated at compile-time, any changes to the class will automatically update these methods too
    • equalsverifier - Provides a way to automatically unit test equals() with reflection - doesn't support testing hashCode()
    0 讨论(0)
  • 2021-02-01 19:56

    How about you write unittests for each class you want to protect. The unit tests should

    1. Use reflection to count the number of fields, and compare with locally stored field names (and types).
    2. If a change in number of fields (or type of fields) has been detected, then invoke hashcode. If the value is the same, then fail the test case. Alert the developer that fields of a class have been changed, and that the developer should : Update the equals and Hashcose, and update the unittest.
    3. Make sure the unittest runs in a nightly build.
    0 讨论(0)
  • 2021-02-01 20:06

    You could serialize your objects to a string using a tool that finds your properties using reflection (XStream, for example), and store that string in a repository. Your unit tests could re-serialize your objects and compare the results to your stored values.

    As part of your own process, make the storage of those strings contingent on manually validating that your hashCode and equals correctly capture all relevant values.

    0 讨论(0)
  • 2021-02-01 20:07

    Never tried it, but how about http://code.google.com/p/equalsverifier/?

    0 讨论(0)
  • 2021-02-01 20:09

    A potential answer seems to be offered in this question.

    I haven't looked into Project Lombok much, but I immediately thought, hmm annotations would work with a code generator.

    0 讨论(0)
提交回复
热议问题