Looking for java Keywords? Try Ask4Keywords

Java Language Pitfall - перегрузка вместо переопределения


пример

Рассмотрим следующий пример:

public final class Person {
    private final String firstName;
    private final String lastName;
   
    public Person(String firstName, String lastName) {
        this.firstName = (firstName == null) ? "" : firstName;
        this.lastName = (lastName == null) ? "" : lastName;
    }

    public boolean equals(String other) {
        if (!(other instanceof Person)) {
            return false;
        }
        Person p = (Person) other;
        return firstName.equals(p.firstName) &&
                lastName.equals(p.lastName);
    }

    public int hashcode() {
        return firstName.hashCode() + 31 * lastName.hashCode();
    }
}

Этот код не будет вести себя так, как ожидалось. Проблема в том, что методы equals и hashcode для Person не переопределяют стандартные методы, определенные Object .

  • Метод equals имеет неправильную подпись. Он должен быть объявлен как equals(Object) не equals(String) .
  • Метод hashcode имеет неправильное имя. Это должен быть hashCode() (обратите внимание на капитал C ).

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

Однако есть простой способ справиться с этим (начиная с Java 5). Используйте аннотацию @Override всякий раз, когда вы планируете переопределить ваш метод:

Java SE 5
public final class Person {
    ...

    @Override
    public boolean equals(String other) {
        ....
    }

    @Override
    public hashcode() {
        ....
    }
}

Когда мы добавим @Override аннотации к объявлению метода, компилятор проверяет , что метод не переопределить (или реализацию) метод , объявленный в суперклассе или интерфейсе. Итак, в приведенном выше примере компилятор даст нам две ошибки компиляции, которых должно быть достаточно, чтобы предупредить нас об ошибке.