Я невежествен здесь...
1: private static class ForeignKeyConstraint implements Comparable {
2: String tableName;
3: String fkFieldName;
4:
5: public int compareTo(ForeignKeyConstraint o) {
6: if (this.tableName.compareTo(o.tableName) == 0) {
7: return this.fkFieldName.compareTo(o.fkFieldName);
8: }
9: return this.tableName.compareTo(o.tableName);
10: }
11: }
В строке 6 я добираюсь от FindBugs: Bug: net.blabla.SqlFixer$ForeignKeyConstraint defines compareTo(SqlFixer$ForeignKeyConstraint) and uses Object.equals()
Я не знаю, как исправить это.
Эта ошибка означает, что вы не переопределяете равняется
в ForeignKeyConstraint
(и, таким образом, наследование равно
от Object
), поэтому следующее неверно (из javadoc compareTo
):
Настоятельно рекомендуется, но строго не требуется, чтобы
(x.compareTo (y) == 0) == (x.equals (y))
. Вообще говоря, любой класс, реализующий интерфейс Comparable и нарушающий это условие, должен четко указывать на этот факт. Рекомендуемый язык: «Примечание: этот класс имеет естественный порядок, несовместимый с equals».
Чтобы исправить проверку FindBugs, переопределите , равный
- и hashCode
- если он делает смысл, который обычно имеет место (или исключите проверку для этого класса и документ, что ваш класс нарушает это условие, используя предложенное примечание).
Вы можете решить эту проблему, реализовав метод equals (). См. Определение FindBugs:
«Как правило, значение compareTo должно возвращать ноль, если и только если equals возвращает истину. Если это нарушено, в таких классах, как PriorityQueue, будут возникать странные и непредсказуемые сбои»
«Это настоятельно рекомендуется, но не обязательно, чтобы (x.compareTo (y) == 0) == (x.equals (y)) »
Другой пример - TreeSet. Он реализует проверки равенства путем вызова compareTo, а реализация compareTo, несовместимая с equals, заставляет TreeSet нарушать контракт интерфейса Set, что может привести к сбоям в работе программы.
Это говорит о том, что есть вероятность несогласия между compareTo () и equals (). И они, действительно, никогда не должны не соглашаться.
Метод equals () наследуется от java.lang.Object, который по умолчанию проверяет, являются ли два объекта одним и тем же экземпляром . Ваш метод compareTo сравнивает объекты на основе tableName и fkFieldName.Таким образом, вы потенциально можете оказаться в ситуации, когда compareTo заявляет, что два объекта одинаковы (потому что tableName и fkFieldName совпадают), но equals заявляет, что они разные (потому что это разные экземпляры).
Есть несколько API-интерфейсов Java, которые зависят от compareTo и являются согласованными; это часть языка java и считается контрактом на базовом языке. В идеале реализовать метод equals (и hashcode) для проверки равенства на основе tableName и fkFieldName.
Вы пытались переопределить метод equals в SqlFixer.ForeignKeyConstraint?
Я считаю, что предупреждение основано на том, что, как указано в определении, могут произойти странные вещи, если вы переопределите compareTo, а не equals.
Для получения дополнительной информации см. Эффективная Java Джошуа Блоха, 2-е издание . В пункте 12 более подробно рассказывается о тонкостях реализации Comparable и некоторых вещах, на которые следует обратить внимание.