более короткий метод равняется тому же как более длинный метод равных? - PullRequest
0 голосов
/ 13 мая 2019

Являются ли два метода equals одинаковыми?:

("версия 1" была сгенерирована Eclipse ide, "версия 2" создана мной.)

версия 1:

public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (!(obj instanceof CoreSale))
            return false;
        User other = (User) obj;
        return Objects.equals(id, other.id);
    }

версия 2 (короче):

public boolean equals(Object obj) {
        // always return false, if not instance of User
        if (obj instanceof CoreSale){
        User other = (User) obj;
        return Objects.equals(id, other.id);
        }
        return false;

    }

Неявно ли obj instanceof CoreSale проверяет this == obj или нетобъявить это также в версии 2?

1 Ответ

1 голос
/ 13 мая 2019

Два куска кода должны давать один и тот же ответ, за исключением неясного случая с краями 1 .

Существенные различия между ними:

  1. тест this == obj.
  2. явный obj == null тест.
  3. итоговый if тест

Работа с ними в обратном порядке.

Я бы не ожидал, что это будет иметь значение, написали ли вы это как obj instanceof Type или !(obj instanceof type). Действительно, я ожидаю, что JIT-компилятор оптимизирует на основе «направления», которое обычно принимает ветвь, и генерирует эквивалентный код для обоих случаев.

Оператор instanceof неявно проверяет null, поэтому явный тест obj == null не требуется. Тем не менее, я ожидаю, что JIT-компилятор распознает это и не сгенерирует собственный код для двойной проверки на ноль.

Тест this == obj реализует явное «короткое замыкание» для случая, который считается часто встречающимся.

  • Пограничный регистр означает, что JIT-компилятор не сможет вставить эквивалентную логику короткого замыкания, если ее еще не было в исходном / байт-кодах.

  • Неясно, улучшится ли короткое замыкание или нет. Это зависит от фактической частоты, с которой один из этих объектов сравнивается с самим собой ... от стоимости выполнения этого.

Короче говоря, только тест this == other может иметь значение (после JIT-компиляции), и это может или не может быть полезным для производительности.

ОДНАКО ... если производительность действительно имеет значение, сравните ее ... используя реалистичные данные для сравнения.


1 - крайний случай возникает, потому что Objects.equals(id, other.id) может вызвать исключение или дать неправильный ответ, когда this.id и other.id - это один и тот же объект. Это, в свою очередь, зависит от фактической реализации Object::equals(Object) для фактического типа времени выполнения id.

...