似乎Android Studio / Gradle 3.4引入了新的皮棉错误DiffUtilEquals
。它通过具有DiffUtil<Any>
然后在oldItem == newItem
函数中作为后备areContentsTheSame
来触发。短绒投掷的错误是
Suspicious equality check: equals() is not implemented in Object
示例代码:
override fun areContentsTheSame(oldItem: Any, newItem: Any): Boolean {
return when {
oldItem is MyKotlinClass && newItem is MyKotlinClass -> true
oldItem is MyKotlinClass2 && newItem is MyKotlinClass2 -> oldItem.title == newItem.title
else -> oldItem == newItem // Lint error on this line
}
}
对于具有多种类型的适配器,在DiffUtil中,这种when语句在DiffUtil中非常普遍,您可以根据它们的类来比较每种类型。
处理此错误的最佳方法是什么?应该将<Any>
更改为类似于Equatable
的某个接口,还是适配器中使用的所有类都应该实现某个接口,该接口包括一种比较它们的方法?
答案 0 :(得分:7)
所有java.lang.Object
都具有equals()
功能。这是语言基础的一部分。但是,并非所有人都可以覆盖它,而这正是棉短绒触发的原因。 (SomeClass() as Any).equals(SomeClass())
可以很好地编译实例(假设您有一个名为SomeClass
的类)。
我不能只用任何一个类来重现它-它必须成为您提到的那个类(DiffUtil.ItemCallback
。我扩大了检查范围,说:
可疑的相等性检查:equals()未在对象中实现
DiffUtil使用检查信息:areContentsTheSame来生成差异。如果该方法的实现不正确,例如使用等号代替等号,或者在尚未实现该方法的类上调用相等,则会出现奇怪的视觉伪像。
此答案最好用不同的代码段演示:
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或Java中缺少identity checking(==
===
(在Kotlin中)。但是,===
会引发一条单独的消息,实际上很容易确定解决方案:
可疑的相等性检查:您是说
==
而不是===
吗?
我想Java中的==
会发出类似的消息,但是建议使用equals
作为替代。 我尚未验证此
关于解决方案:
您可以抑制或更改严重性以防止错误。更改严重性或全局抑制在同一位置。文件->设置->编辑器->检查> Android->棉绒->正确性->可疑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!
}
}
}
答案 1 :(得分:2)
所有您需要做的就是在POJO类中重写equals(),瞧瞧这个错误将消失