gpt4 book ai didi

android - Lint 错误 : Suspicious equality check: equals() is not implemented in Object DiffUtilEquals

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:55:54 41 4
gpt4 key购买 nike

Android Studio/Gradle 3.4 似乎引入了一个新的 lint 错误 DiffUtilEquals .它由 DiffUtil<Any> 触发然后调用作为后备 oldItem == newItemareContentsTheSame功能。 linter 抛出的错误是

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
}
}

这种 when 语句在 DiffUtil 中对于具有多种类型的适配器非常常见,您可以根据它们的类比较每种类型。

处理此错误的最佳方法是什么?应该<Any>更改为类似于 Equatable 的界面或者适配器中使用的所有类都应该实现一些接口(interface),其中包括比较它们的方法?

最佳答案

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

我无法用任何类重现它 - 它必须是你提到的那个(DiffUtil.ItemCallback)。我扩大了检查范围,上面写着:

Suspicious equality check: equals() is not implemented in Object

Inspection info:areContentsTheSame is used by DiffUtil to produce diffs. If the method is implemented incorrectly, such as using identity equals instead of equals, or calling equals on a class that has not implemented it, weird visual artifacts can occur.

这个答案最好用不同的 fragment 来证明:

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
}

}

这将编译。如果您不知道,数据类 会生成一个自定义的equals 方法。如果您在 Android Studio 中删除 data 关键字,错误将再次出现,因为没有重写的 equals 方法。

TL;DR: 检查提示缺少自定义 equals 方法,和/或使用 identity checking (Java 中的 == 或 Kotlin 中的 ===)。但是,=== 将引发一条单独的消息,该消息更容易实际确定解决方案:

Suspicious equality check: Did you mean == instead of ===?

我想 Java 中的 == 会引发类似的消息,但建议使用 equals 作为替代。 我还没有验证过

至于解决方案:

如果你知道自己在做什么(不推荐)

您可以抑制或更改错误的严重性。更改严重性或全局抑制在同一个地方。文件 -> 设置 -> 编辑器 -> 检查 > Android -> Lint -> 正确性 -> 可疑的 DiffUtil 相等性

enter image description here

或者您可以通过以下方式在本地抑制它:

@SuppressLint("DiffUtilEquals")

如果你想安全行事

不幸的是,这更复杂。

Any no guarantee equals 被覆盖 - 因此检查。您真正拥有的唯一可行选择是使用不同的类。使用 Equatable 也不是一个坏主意。然而,与 Any 不同的是,这不是默认实现的。事实上,它不存在于 SDK 中。但是,您可以自己创建一个。

要注意的是,任何实现类现在需要一个equals 方法。如果您使用 data classes,这不是问题(我已经在代码中演示了这一点)。但是,如果不这样做,则需要手动实现。此处手动意味着您编写它,或者以其他方式生成它(对于带有注释的实例)。

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!
}
}
}

关于android - Lint 错误 : Suspicious equality check: equals() is not implemented in Object DiffUtilEquals,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55895359/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com