Disclaimer: I am the author of jaxb2-basics , which provides JAXB2 plugins capable of generating hashCode and equals .
Here's a usage example for Maven:
<plugin> <groupId>org.jvnet.jaxb2.maven2</groupId> <artifactId>maven-jaxb2-plugin</artifactId> <executions> <execution> <goals> <goal>generate</goal> </goals> </execution> </executions> <configuration> <extension>true</extension> <args> <arg>-Xequals</arg> <arg>-XhashCode</arg> </args> <plugins> <plugin> <groupId>org.jvnet.jaxb2_commons</groupId> <artifactId>jaxb2-basics</artifactId> <version>...</version> </plugin> </plugins> </configuration> </plugin>
(See the documentation for Ant.)
You can use -XsimpleHashCode and -XsimpleEquals , which generate hashCode and equals methods without execution at run time (hash code or equivalent calculation) or -XhashCode / -Xequals , which generate the "strategic" hashCode and equals methods (hash code / Equal computing is delegated to accepted strategic methods).
Here -XsimpleHashCode generates:
public class Customer { ... public int hashCode() { int currentHashCode = 1; { currentHashCode = (currentHashCode* 31); String theAddress; theAddress = this.getAddress(); if (theAddress!= null) { currentHashCode += theAddress.hashCode(); } } { currentHashCode = (currentHashCode* 31); Boolean theBlueEyes; theBlueEyes = this.isBlueEyes(); if (theBlueEyes!= null) { currentHashCode += theBlueEyes.hashCode(); } } { currentHashCode = (currentHashCode* 31); String theFamilyName; theFamilyName = this.getFamilyName(); if (theFamilyName!= null) { currentHashCode += theFamilyName.hashCode(); } } { currentHashCode = (currentHashCode* 31); String theGivenName; theGivenName = this.getGivenName(); if (theGivenName!= null) { currentHashCode += theGivenName.hashCode(); } } { currentHashCode = (currentHashCode* 31); List<String> theMiddleInitials; theMiddleInitials = (this.isSetMiddleInitials()?this.getMiddleInitials():null); if (theMiddleInitials!= null) { currentHashCode += theMiddleInitials.hashCode(); } } { currentHashCode = (currentHashCode* 31); String thePostCode; thePostCode = this.getPostCode(); if (thePostCode!= null) { currentHashCode += thePostCode.hashCode(); } } { currentHashCode = (currentHashCode* 31); boolean theSingle; theSingle = this.isSingle(); currentHashCode += (theSingle? 1231 : 1237); } return currentHashCode; } }
Here, -XhashCode generates:
public class Customer implements HashCode { ... public int hashCode(ObjectLocator locator, HashCodeStrategy strategy) { int currentHashCode = 1; { String theAddress; theAddress = this.getAddress(); currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "address", theAddress), currentHashCode, theAddress); } { Boolean theBlueEyes; theBlueEyes = this.isBlueEyes(); currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "blueEyes", theBlueEyes), currentHashCode, theBlueEyes); } { String theFamilyName; theFamilyName = this.getFamilyName(); currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "familyName", theFamilyName), currentHashCode, theFamilyName); } { String theGivenName; theGivenName = this.getGivenName(); currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "givenName", theGivenName), currentHashCode, theGivenName); } { List<String> theMiddleInitials; theMiddleInitials = (this.isSetMiddleInitials()?this.getMiddleInitials():null); currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "middleInitials", theMiddleInitials), currentHashCode, theMiddleInitials); } { String thePostCode; thePostCode = this.getPostCode(); currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "postCode", thePostCode), currentHashCode, thePostCode); } { boolean theSingle; theSingle = this.isSingle(); currentHashCode = strategy.hashCode(LocatorUtils.property(locator, "single", theSingle), currentHashCode, theSingle); } return currentHashCode; } public int hashCode() { final HashCodeStrategy strategy = JAXBHashCodeStrategy.INSTANCE; return this.hashCode(null, strategy); } }
From my PoV, the "strategic" versions are more powerful. Classes implement hashCode or equals interfaces that accept locators and hash code / equivalent strategies. This allows you to control the calculation or comparison of the hash code from the outside. I often use this in unit tests to not only check if two objects are the same or not, but also to find out where they differ.
Both plug-ins generate methods without reflections (this is important for performance). They also consider special JAXB cases like JAXBElement s, primitive arrays, etc.