Отражение в Apache равнозначно рассмотрению родителей и детей как равных - PullRequest
0 голосов
/ 22 мая 2018

Apache EqualsBuilder.reflectionEquals(...) может рассматривать 2 разных типа как равные, если они имеют одинаковые атрибуты.Должно ли поведение равных вести себя?

public static void main(String[] args) {

    class A {
        protected int x = 1;
    }

    class B extends A {
    }

    System.out.println(EqualsBuilder.reflectionEquals(new A(), new B()));
    System.out.println(EqualsBuilder.reflectionEquals(new A(), new B(), false, B.class));
}

Вывод:

true
true

Я провел тот же эксперимент с автоматически сгенерированными равными IntelliJ IDEA, и он рассматривает оба объекта по-разному:

public static void main(String[] args) {
    class A {
        protected int x = 1;

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            A a = (A) o;
            return x == a.x;
        }
    }

    class B extends A {
    }

    System.out.println(new A().equals(new B()));
}

Выход:

false

1 Ответ

0 голосов
/ 22 мая 2018

Если вы посмотрите на источник , соответствующая часть - это строки 477-500:

477        // Find the leaf class since there may be transients in the leaf
478        // class or in classes between the leaf and root.
479        // If we are not testing transients or a subclass has no ivars,
480        // then a subclass can test equals to a superclass.
481        final Class<?> lhsClass = lhs.getClass();
482        final Class<?> rhsClass = rhs.getClass();
483        Class<?> testClass;
484        if (lhsClass.isInstance(rhs)) {
485            testClass = lhsClass;
486            if (!rhsClass.isInstance(lhs)) {
487                // rhsClass is a subclass of lhsClass
488                testClass = rhsClass;
489            }
490        } else if (rhsClass.isInstance(lhs)) {
491            testClass = rhsClass;
492            if (!lhsClass.isInstance(rhs)) {
493                // lhsClass is a subclass of rhsClass
494                testClass = lhsClass;
495            }
496        } else {
497            // The two classes are not related.
498            isEquals = false;
499            return this;
500        }

Так что они специально решили разрешить это.

Правила для equals допускают и этот подход, и тот, который используется IDEA (и, как мне кажется, большинством других автоматических генераторов).

Но как часть EqualsBuilder, текущий подход может быть предпочтительнее, потому что как только проверка возвращает false, это конечный результат, тогда как true может стать false, сравнивая классы какхорошо.

...