FindBugs противоречивое описание - PullRequest
1 голос
/ 22 марта 2010

Я правильно понимаю, или описание неверное?

Равно проверяет несовместимый операнд (EQ_CHECK_FOR_OPERAND_NOT_COMPATIBLE_WITH_THIS)

Этот метод equals проверяет, является ли аргумент некоторымнесовместимый тип (т. е. класс, который не является ни супертипом, ни подтипом класса, определяющего метод equals).Например, класс Foo может иметь метод equals, который выглядит следующим образом:

public boolean equals(Object o) {
  if (o instanceof Foo)
    return name.equals(((Foo)o).name);
  else if (o instanceof String)
    return name.equals(o);
  else return false;

Это считается плохой практикой, поскольку очень трудно реализовать симметричный метод equalsи переходный.Без этих свойств возможны очень неожиданные поведения.

From: http://findbugs.sourceforge.net/bugDescriptions.html#EQ_CHECK_FOR_OPERAND_NOT_COMPATIBLE_WITH_THIS

В описании говорится, что класс Foo может иметь такой метод equals, а после него говорится, что«Это считается плохой практикой».Я не понимаю "правильный путь" ..

Каким должен быть следующий метод, чтобы быть правильным?

@Override
public boolean equals(Object obj) {
if (obj instanceof DefaultTableModel)
    return model.equals((DefaultTableModel)obj);
else
    return false;
}

Ответы [ 3 ]

4 голосов
/ 22 марта 2010

Когда в описании FindBugs говорится, что "может быть так и есть", они говорят не о том, что это приемлемая практика, а о том, что это гипотетическое обстоятельство, которое может привести к соответствующему предупреждению.

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

DefaultTableModel dtm = new DefaultTableModel(...);
YourObject foo = new YourObject(dtm);
foo.equals(dtm); // true
dtm.equals(foo); // false!
3 голосов
/ 22 марта 2010

Проблема с первой версией метода (на что жалуется FindBugs) заключается в том, что он НЕ симметричен .

Если у вас есть объект Foo f, для которого f.equals("someName") равен true, то симметрия говорит, что "someName".equals(f) также должно быть true. Но вы не можете реализовать это: "someName".equals(...) вернет false для любого параметра, который не является строкой.

Вторая версия метода также неверна, поскольку вы говорите, что экземпляр Foo может быть равен экземпляру DefaultTableModel ... но не другому экземпляру Foo. Это означает, что экземпляр Foo не может быть равен самому себе, и поэтому equals является НЕ рефлексивным . Кроме того, неясно, что такое идентификатор model ...

0 голосов
/ 03 июня 2010

Необычной частью вашей реализации является то, что вы сравниваете поле "модель" с полным объектом "obj" .Обычно вы должны сравнивать каждое поле себя с каждым полем другого объекта после того, как проверили, что они оба принадлежат к одному и тому же классу или подклассу.

...