Все java.lang.Object
имеют функцию equals()
. Это часть основы языка. Однако не все переопределяют его, и это то, что запускает линтер. (SomeClass() as Any).equals(SomeClass())
прекрасно скомпилируется для экземпляра (если, конечно, у вас есть класс с именем SomeClass
).
Я не мог воспроизвести это ни с одним классом - у него было , которое вы упомянули (DiffUtil.ItemCallback
). Я расширил инспекцию, которая говорит:
Подозрительная проверка на равенство: функция equals () не реализована в Object
Информация о проверке: areContentsTheSame используется DiffUtil для создания различий. Если метод реализован неправильно, например, при использовании идентификаторов равных вместо равных или при вызове равных в классе, который его не реализовал, могут возникнуть странные визуальные артефакты.
Этот ответ лучше всего продемонстрировать в другом фрагменте:
data class One(val t: String)
val x = object : DiffUtil.ItemCallback<One>() {
override fun areItemsTheSame(p0: One, p1: One): Boolean { TODO() }
override fun areContentsTheSame(p0: One, p1: One): Boolean {
return p0 == p1
}
}
Это скомпилируется. Если вы не знаете, data class
генерирует пользовательский метод equals
. Если в Android Studio удалить ключевое слово data
, ошибка появится снова, поскольку переопределенный метод получения отсутствует.
TL; DR: Инспекция жалуется на отсутствие пользовательского equals
метода и / или использования проверки личности (==
в Java или * 1032) * в Котлине). Тем не менее, ===
выдаст отдельное сообщение, которое на самом деле значительно проще идентифицировать решение:
Подозрительная проверка на равенство: Вы имели в виду ==
вместо ===
?
И я представляю, ==
в Java вызывает подобное сообщение, но с equals
в качестве предлагаемой замены. Я не проверял это
Что касается решений:
Если вы знаете, что делаете
Вы можете подавить или изменить серьезность ошибки. Изменение серьезности или подавление глобально - там же. Файл -> Настройки -> Редактор -> Проверки> Android -> Lint -> Корректность -> Подозрительный DiffUtil равенства
Или вы можете подавить его локально с помощью:
@SuppressLint("DiffUtilEquals")
Если вы хотите быть осторожным
Это, к сожалению, сложнее.
Any
имеет без гарантии equals
отменено - следовательно, проверка. Единственный возможный вариант - использовать другой класс. И использование Equatable
тоже неплохая идея. Однако, в отличие от Any, по умолчанию это не реализовано. На самом деле его нет в SDK. Но Kotlin позволяет легко исправить. Вы можете создать это самостоятельно.
Уловка в том, что любой из реализующих классов теперь нуждается в метод equals. Если вы используете data class
es, это не проблема (и я продемонстрировал это в коде). Однако, если вы этого не сделаете, вам нужно будет реализовать это вручную. Или я представляю с аннотацией, но вам, вероятно, придется создать ее самостоятельно или найти библиотеку, которая добавляет такую функциональность.
interface Equatable {
override fun equals(other: Any?) : Boolean;
}
data class One(val t: String) : Equatable
data class Two(val title: String) : Equatable
val x = object : DiffUtil.ItemCallback<MySharedItemClass>() {
override fun areItemsTheSame(p0: MySharedItemClass, p1: MySharedItemClass): Boolean {
TODO("not implemented")
}
override fun areContentsTheSame(p0: MySharedItemClass, p1: MySharedItemClass): Boolean {
return when {
p0 is One && p1 is One -> true
p0 is Two && p1 is Two -> p0.title == p1.title
else -> p0 == p1 // No error!
}
}
}