Я заметил что следующий отрывок...
@Override
public boolean equals(Object otherObject) {
...
}
... не позволяется для Перечисления, начиная с метода equals(Object x)
определяется как final
в Enum
. Почему это так?
Я не могу думать ни о каком варианте использования, который потребовал бы переопределения equals(Object)
для Перечисления. Мне просто любопытно знать обоснование позади этого поведения.
Все, что угодно, кроме вернуть this == other
, противоречит интуиции и нарушает принцип наименьшего удивления . Предполагается, что две константы перечисления будут равны
тогда и только тогда, когда они являются одним и тем же объектом, и возможность переопределения этого поведения может привести к ошибкам.
Те же рассуждения применимы к hashCode ()
, clone ()
, compareTo (Object)
, name ()
, ] ordinal ()
и getDeclaringClass ()
.
JLS не мотивирует выбор сделать его окончательным, но упоминает равенства в контексте перечислений здесь . Фрагмент:
Метод equals в
Enum
- это последний метод, который просто вызываетsuper.equals
для своего аргумента и возвращает результат, таким образом выполняя сравнение идентичности.
Я должен признаться, что перечисления - это последнее, что я хотел бы переопределить equals ()
в.
Я думаю, что причина equals ()
является окончательной в перечислениях в том, что Java поощряет ==
для сравнения перечислений, а реализация equals ()
в перечислениях просто использует его, поэтому разрешение отмены equals ()
предотвращает ==
и equals ()
из-за разного поведения, чего другие разработчики не ожидают.
Уже существует сильное интуитивное представление о том, что значит для экземпляров (значений) enum
быть равными. Допущение перегрузки метода equals
приведет к нарушению этого понятия, что приведет к неожиданному поведению, ошибкам и так далее.
Именно потому, что Java-дизайнеры не могли придумать какой-либо мыслимый вариант использования для переопределения Enum.equals(Object), этот метод объявляется окончательным - так что такое переопределение было бы невозможно.