Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
2.0
-
None
-
None
-
Operating System: All
Platform: All
-
33069
Description
Append two arrays of any object type to an EqualsBuilder using EqualsBuilder.append(Object[],
Object[]) – we'll call the first 'lhs' and the second 'rhs'. If, for any i, lhs[i] is not null, rhs[i] is not null,
and rhs[i] is not of the same type as, or a subtype of, lhs[i], then the EqualsBuilder will return false.
However, this behavior is incorrect. While rare, it is perfectly valid in Java to define an equals() method
on a class A that will return true when passed in an object of some class B, where B is not the same as A
nor a subtype of A. (A conceptual example is comparing a RGBColor to a CMYKColor, where RGBColor is
not a subclass of CMYKColor, nor vice-versa. In this example, the EqualsBuilder will return false,
whether the equals() method is defined on RGBColor to explicitly check CMYKColors, or even if you
define a base-class Color.equals() method that does an abstract comparison.)
To reproduce:
public static class A {
private int a;
public A(int a)
public boolean equals(Object o)
{ if (o == this) return true; if (o instanceof A) return this.a = ((A) o).getA(); if (o instanceof B) return this.a = ((B) o).getB(); return false; }public int getA()
{ return this.a; }}
public static class B {
private int b;
public B(int b)
public boolean equals(Object o)
{ if (o == this) return true; if (o instanceof A) return this.b = ((A) o).getA(); if (o instanceof B) return this.b = ((B) o).getB(); return false; }public int getB()
{ return this.b; }}
Object[] x = new Object[]
{ new A(1) };
Object[] y = new Object[]
;
System.err.println("x[0].equals(y[0])? " + x[0].equals(y[0]));
System.err.println("Does EqualsBuilder think the arrays are equal? " + (new EqualsBuilder().append(x,
y).isEquals()));
This program will output:
true
false
The attached patch adds to an existing unit-test case some code that proves the existence of this bug,
and also fixes it. (It also fixes COM-1842.)