Skip to content

Instantly share code, notes, and snippets.

@onero
Created July 21, 2020 09:46
Show Gist options
  • Select an option

  • Save onero/54f61293d9775deb8ca3b71ecc4e1164 to your computer and use it in GitHub Desktop.

Select an option

Save onero/54f61293d9775deb8ca3b71ecc4e1164 to your computer and use it in GitHub Desktop.
Equals Template for IntelliJ using instanceof, instead of getClass
#parse("equalsHelper.vm")
public boolean equals(##
#if ($settings.generateFinalParameters)
final ##
#end
Object $paramName){
#addEqualsPrologue()
#addClassInstance()
return ##
#set($i = 0)
#foreach($field in $fields)
#if ($i > 0)
&&
#end
#set($i = $i + 1)
#if ($field.primitive)
#if ($field.double || $field.float)
#addDoubleFieldComparisonConditionDirect($field) ##
#else
#addPrimitiveFieldComparisonConditionDirect($field) ##
#end
#elseif ($field.enum)
#addPrimitiveFieldComparisonConditionDirect($field) ##
#elseif ($field.array)
java.util.Arrays.equals($field.accessor, ${classInstanceName}.$field.accessor)##
#elseif ($field.notNull)
${field.accessor}.equals(${classInstanceName}.$field.accessor)##
#else
java.util.Objects.equals($field.accessor, ${classInstanceName}.$field.accessor)##
#end
#end
;
}
@onero
Copy link
Author

onero commented Jul 21, 2020

This gist is for adding a equals template to IntelliJ (v14.1+) that uses an instanceof implementation, instead of getClass, in the case that a non-final class overrides of the equals method.
To read more about this issue I can recommend the following sources:
instanceof or getClass
instanceof versus getClass in equals Methods

@AFulgens
Copy link

AFulgens commented Oct 8, 2025

I am as of Java 21 using the following template, that copies/overwrites some of the stuff from the IntelliJ baked-in template:

#parse("equalsHelper.vm")
#set($paramName = "other")
#set($classInstanceName = "that")
public boolean equals(##
#if ($settings.generateFinalParameters)
  final ##
#end
Object $paramName){
if (this == $paramName) {
  return true;
}

if (!($paramName instanceof $classname#generateWildcards() $classInstanceName)) {
  return false;
}
#if ($superHasEquals)

if(!super.equals($paramName)) {
  return false;
}
#end

return ##
#set($i = 0)
#foreach($field in $fields)
  #if ($i > 0)
  
  && ##
  #end
  #set($i = $i + 1)
  #if ($field.primitive)
    #if ($field.double || $field.float)
      #addDoubleFieldComparisonConditionDirect($field) ##
    #else
      #addPrimitiveFieldComparisonConditionDirect($field) ##
    #end
  #elseif ($field.enum)
    #addPrimitiveFieldComparisonConditionDirect($field) ##
  #elseif ($field.array)
  java.util.Objects.deepEquals($field.accessor, ${classInstanceName}.$field.accessor)##
  #else
  java.util.Objects.equals($field.accessor, ${classInstanceName}.$field.accessor)##
  #end
#end
;
}

Example output (null-check is superfluous because of the magic of instanceof):

@Override
public boolean equals(Object other) {
	if (this == other) {
		return true;
	}

	if (!(other instanceof MyAwesomeClass<?> that)) {
		return false;
	}

	return Objects.equals(source, that.source)
		&& Objects.equals(id, that.id)
		&& Objects.equals(context, that.context);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment