似乎Android Studio / Gradle 3.4引入了新的lint错误DiffUtilEquals
。它可以通过在函数中具有a DiffUtil
然后作为后备调用来触发。短绒投掷的错误是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 } }
对于具有多种类型的Adapter,在DiffUtil中,这种when语句将很常见,在该适配器中,您可以根据类比较每种类型。
处理此错误的最佳方法是什么?应该
更改为类似的接口,Equatable
或者适配器中使用的所有类都应该实现某种包含比较它们的方法的接口?
所有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() { 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或===
Kotlin中)。但是,这===
将引发一条单独的消息,实际上更容易确定解决方案:
可疑的平等检查:您是
==
不是要指===
?
而且我想==
在Java中会引发类似的消息,但equals
建议使用替代方法。我尚未验证
至于解决方案:
如果你知道自己在做什么您可以抑制或更改严重性以防止错误。更改严重性或全局抑制在同一位置。文件->设置->编辑器->检查> Android->棉绒->正确性->可疑DiffUtil相等
或者您可以使用以下方法在本地禁止显示:
@SuppressLint("DiffUtilEquals")如果你想安全玩
不幸的是,这更加复杂。
Any
有没有保证 equals
是重写-因此检查。您真正唯一可行的选择是使用其他类。而且使用Equatable
a也不错。但是,与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() { 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! } } }