[
https://issues.apache.org/jira/browse/LANG-1499?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17132766#comment-17132766
]
Miguel Munoz commented on LANG-1499:
------------------------------------
I'm just brainstorming here, so please nit-pick. But here's one possible fix:
Allow the user to specify which parent class to use for doing the comparison.
So, for the revised test case, the C.equals() method would look more like this:
{code:java}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (!(o instanceof C)) { // implicit test for null
return false;
}
return EqualsBuilder.reflectionEquals(this, o, C.class); // new parameter
to solve this problem.
}
{code}
Here, if the equals() method is called from an instance of D or E, or any
subclass of C, it still knows to do the reflection from class C instead of
this.getClass().
This assumes that whoever wrote class C knows that it will be subclassed, and
that subclasses should still use the equals() method of class C. Zhiqiang
Zang's point about LinkedList and ArrayList is a good example of where the
author of the base class would know this about its subclasses.
However, this fix doesn't address the opposite case where class C is a generic
base class, and the author expects subclasses to use their own properties in
the equals method. On my last job, our JPA entity classes were written this
way. As far as I know, it didn't cause a problem, because the code probably
didn't compare objects of different types, but I can't be sure about that.
Here's another problem with my proposed approach. The reflectionEquals() method
is already overloaded, with one alternate taking a class instance named
reflectUpTo. We would need a way to clearly distinguish this new starting point
from the reflectUpTo, which is an ending point.
> Equals transitivity is violated in EqualsBuilder
> ------------------------------------------------
>
> Key: LANG-1499
> URL: https://issues.apache.org/jira/browse/LANG-1499
> Project: Commons Lang
> Issue Type: Bug
> Components: lang.builder.*
> Affects Versions: 3.9
> Environment: Ubuntu 18.04
> JDK 1.8.0_221
> Commons Lang 3.9-RC2
> JUnit 5.4
> Reporter: Zhiqiang Zang
> Priority: Major
> Labels: Equals(), EqualsBuilder, transitivity
> Attachments: EqualTransitivityTest2.java, EqualsTransitivityTest.java
>
>
> EqualsBuilder.reflectionEquals() does not hold transitivity when comparing
> two subclasses extending a common superclass. For example:
> Given that both class D and E are subclasses of class C, C == D and C == E
> should imply D == E. However EqualsBuilder.reflectionEquals(D, E) returns
> *false* when both EqualsBuilder.reflectionEquals(C, D) andÂ
> EqualsBuilder.reflectionEquals(C, E) return true.
> A junit test is provided as attachment.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)