Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare objects of different classes using reflection

Tags:

I've got two objects with exactly the same attributes. Don't ask me why, this is generated code and I have to deal with this.

class Bean1 {
   int id;
}

class Bean2 {
   int id;
}

I want to compare objects of each class without writing the compare code for each attribute. This thread explains how to compare two objects but in my case this fails because they are not of instances of the same class.

This code returns false:

EqualsBuilder.reflectionEquals(new Bean1(1), new Bean2(1));

Is there another way to comapre objects and ignore object classes?

like image 835
jaudo Avatar asked Feb 05 '19 15:02

jaudo


2 Answers

I was finally able to do this with Apache Common Lang's ReflectionToStringBuilder, because it provides a ToStringStyle.NO_CLASS_NAME_STYLE option.

Furthermore, as I'm using it with JUnit test, it's useful because if the objects are differents, I will be able to see which field is different.

Assert.assertEquals(
   new ReflectionToStringBuilder(bean1, ToStringStyle.NO_CLASS_NAME_STYLE).toString(),
   new ReflectionToStringBuilder(bean2, ToStringStyle.NO_CLASS_NAME_STYLE).toString());
like image 129
jaudo Avatar answered Sep 30 '22 07:09

jaudo


Unless you find a library that does that, you can always write your own reflection code that does what you need:

  • query the fields on your objects to compare
  • compare their content in case both sets of field names are equal
  • not take the actual class into account

If you are really dealing with such "simple" bean classes, implementing this yourself might actually not be too big of a deal.

Alternatively, you could create a generator like

public Bean1 from(Bean2 incoming) { ...

If you know your classes, you can "pull" all values from a Bean2 into a Bean1 instance, and then you can compare two Bean1 instances.

But of course, that idea is not helpful (it requires you to write code to treat all fields, or to again use reflection), but we can easily extend that to a non-reflection way: serialize your Bean2 to JSON, using GSON for example. Then de-serialize that JSON string into a Bean1!

So: if you don't find a library that does that reflection based equal ignoring the class, you should be able to JSON serialization to get to two objects of the same class.

like image 30
GhostCat Avatar answered Sep 30 '22 08:09

GhostCat