Переопределение equals () в подклассе класса, который содержит переопределенный equals () - PullRequest
2 голосов
/ 06 февраля 2012

У меня есть класс Point и класс MinesweeperSquare, последний является подклассом первого. Если я переопределю метод equals в последнем, вот так:

if (!(obj instanceof MinesweeperSquare)) {
  return false;
}

FindBugs сообщает, что:

Этот класс определяет метод equals, который переопределяет метод equals в суперклассе. Оба равных метода методы используют instanceof при определении того, равны ли два объекта. Это чревато опасностью, поскольку важно, чтобы метод equals был симметричным (другими словами, a.equals(b) == b.equals(a)). Если B является подтипом A, и метод equals A проверяет, что аргумент является экземпляром A, и метод equals B проверяет, что аргумент является экземпляром B, вполне вероятно, что отношение эквивалентности, определенное этими методы не симметричны.

В классе Point я написал:

if (!(obj instanceof Point)) {
  return false;
}

Как мне написать equals метод в MinesweeperSquare, чтобы метод equals был симметричным?

Обновление

FindBugs не сообщает об ошибках, если я пишу следующее в MinesweeperSquare:

if (o == null || this.getClass() != o.getClass()) {
  return false;
}

Ответы [ 3 ]

3 голосов
/ 06 февраля 2012

В вашем новом методе MinesweeperSquare.equals(Point) всегда будет возвращать false, но Point.equals(MinesweeperSquare) может вернуть true.Хорошо, что вы нашли FindBugs для такого рода вещей.Возможно, вы сможете использовать getClass() в обоих определениях Point и MinesweeperSquare, чтобы проверить, равны ли классы ... хотя это тоже сложно.

1 голос
/ 06 февраля 2012

Использование instanceof хорошо, если все сделано правильно, что довольно сложно без правильной лекции.Использование

this.getClass().equals(that.getClass())

тривиально, но не всегда делает то, что вам нужно.Посмотрите здесь для canEqual.

РЕДАКТИРОВАТЬ

Все это применимо только тогда, когда вы управляете обоими классами, что здесь не так.Так что придерживайся простого пути.

1 голос
/ 06 февраля 2012

Как вы уже упоминали, если вы используете оператор instanceof в реализации метода equals (), он становится несимметричным. Избавьтесь от instanceof в вашем суперклассе, а также от всех подклассов и попробуйте переопределить метод equals (), основываясь на свойствах класса и здравом смысле. Большинство IDE позволяет автоматически генерировать метод equals (), который является хорошей отправной точкой.

...