Android Lint错误:可疑的相等性检查:在对象DiffUtilEquals中未实现equals()

Android Lint错误:可疑的相等性检查:在对象DiffUtilEquals中未实现equals(),android,android-studio,kotlin,android-recyclerview,Android,Android Studio,Kotlin,Android Recyclerview,Android Studio/Gradle 3.4似乎引入了一个新的lint错误DiffUtilEquals。通过使用DiffUtil,然后在AreContentsSame函数中作为回退调用oldItem==newItem,可以触发它。linter抛出的错误是 可疑相等检查:对象中未实现equals() 示例代码: override fun areContentsTheSame(oldItem: Any, newItem: Any): Boolean { return whe

Android Studio/Gradle 3.4似乎引入了一个新的lint错误
DiffUtilEquals
。通过使用
DiffUtil
,然后在
AreContentsSame
函数中作为回退调用
oldItem==newItem
,可以触发它。linter抛出的错误是

可疑相等检查:对象中未实现equals()
示例代码:

 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
        }
    }
这个when语句在DiffUtil中非常常见,因为适配器有多种类型,您可以根据它们的类来比较每种类型


处理此错误的最佳方法是什么?是否应该将
更改为类似于
equalable
的接口,或者适配器中使用的所有类都应该实现一些包含比较它们的方法的接口?

所有
java.lang.Object
都有一个
equals()
函数。它是语言基础的一部分。然而,并不是所有的都会覆盖它,这就是linter触发的原因
(SomeClass()与Any一样)。equals(SomeClass())
可以为实例编译(当然,假设您有一个名为
SomeClass
的类)

我不能用任何类来复制它-它必须是您提到的类(
DiffUtil.ItemCallback
)。我扩大了检查范围,内容是:

可疑的相等性检查:对象中未实现equals()

检验信息:AreContents DiffUtil使用相同的内容来生成差异。如果该方法实现不正确,例如使用identity equals而不是equals,或者对尚未实现它的类调用equals,则可能会出现奇怪的视觉构件

这个答案最好用另一个片段来说明:

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
    }

}
如果你想稳妥行事 不幸的是,这更为复杂

任何
不保证
等于
被覆盖-因此检查。唯一可行的选择是使用不同的类。而且使用
相等的
也不是一个坏主意。但是,与任何其他方法不同,这不是默认实现的。事实上,它并不存在于SDK中。但是,您可以自己创建一个

关键是,任何实现类现在都需要一个equals方法。如果使用
data类
es,这不是问题(我在代码中已经演示了这一点)。但是,如果不这样做,则需要手动实现它。这里的手动意味着要么编写它,要么生成它(对于带有注释的实例)

接口均衡{
覆盖乐趣等于(其他:任何?):布尔值;
}
//数据类生成必要的equals方法。Equatable确保所有子类都实现了它,这修复了检查希望您修复的内容。
数据类1(val t:String):可均衡
数据类2(val标题:字符串):可等式
val x=object:DiffUtil.ItemCallback(){
覆盖项相同(p0:Equalable,p1:Equalable):布尔值{
待办事项(“未实施”)
}
覆盖乐趣内容相同(p0:Equalable,p1:Equalable):布尔值{
何时返回{
p0为1&&p1为1->true
p0为2&&p1为2->p0.title==p1.title
else->p0==p1//无错误!
}
}
}

bro您所需要的只是在POJO类中重写equals(),瞧,这个错误将消失

“对于具有多种类型的适配器,这段代码在DiffUtil中非常常见”——《代码》中的第一种情况似乎很奇怪。内容是一样的。。。纯粹基于Kotlin类是什么?只是一个人为的例子,你是对的,它可能不会发生在现实世界中,但我想保持简单的例子你到底从哪里得到这个类?
中的take int是相同的内容
,并且没有泛型类型。这一个,对不起,这可能是个愚蠢的问题,但是什么是
MySharedItemClass
?我在你的回答中看不到它的实现。@Marat我不知道。假设这是一个打字错误,我的意思是
equalatable
。不知道它从哪里来,但它不应该在那里:')
@SuppressLint("DiffUtilEquals")
interface Equatable  {
    override fun equals(other: Any?) : Boolean;
}

// Data classes generate the necessary equals methods. Equatable ensures all child classes do implement it, which fixes what the inspection wants you to fix.
data class One(val t: String) : Equatable  
data class Two(val title: String) : Equatable  

val x = object : DiffUtil.ItemCallback<Equatable /*Or a higher level inheritance model, i.e. a MySharedItemClass, where it either contains an abstract equals or implements Equatable. Implementing it doesn't require it to be abstract, but it depends on where you want the equals implementation. Equatable is an example of forced equals implementation, but there's many ways to Rome. */>() {
    override fun areItemsTheSame(p0: Equatable, p1: Equatable): Boolean {
        TODO("not implemented")
    }

    override fun areContentsTheSame(p0: Equatable, p1: Equatable): 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!
         }
    }
}