- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
Android Studio/Gradle 3.4 似乎引入了一个新的 lint 错误 DiffUtilEquals
.它由 DiffUtil<Any>
触发然后调用作为后备 oldItem == newItem
在areContentsTheSame
功能。 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 相等性
或者您可以通过以下方式在本地抑制它:
@SuppressLint("DiffUtilEquals")
不幸的是,这更复杂。
Any
no guarantee equals
被覆盖 - 因此检查。您真正拥有的唯一可行选择是使用不同的类。使用 Equatable
也不是一个坏主意。然而,与 Any 不同的是,这不是默认实现的。事实上,它不存在于 SDK 中。但是,您可以自己创建一个。
要注意的是,任何实现类现在需要一个equals 方法。如果您使用 data class
es,这不是问题(我已经在代码中演示了这一点)。但是,如果不这样做,则需要手动实现。此处手动意味着您编写它,或者以其他方式生成它(对于带有注释的实例)。
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/
在 Sitecore 中,我尝试在线路管理器中创建分段列表。但是,当我选择条件时,我对“等于”、“不区分大小写等于”和“不不区分大小写等于”感到非常困惑? 谁能给我解释一下其中的区别吗? 谢谢! 最佳
基本上,我想知道在这种情况下我是否应该听 ReSharper... 您认为与字符进行比较应该使用 Char.Equals(char),因为它可以避免拆箱,但 Resharper 建议使用 Object
假设 equals() 是可传递的;我知道如果 x 和 y 有平等的双边协议(protocol),那么其中一个,比如 y,不会单独与第三类 z 签订协议(protocol)。 但是如果我们遇到 x.e
我是 Haskell 新手,正在阅读: http://www.seas.upenn.edu/~cis194/spring13/lectures/01-intro.html 它指出“在 Haskell
阅读有关 C# 中的字符串比较的文章,我发现有很多方法可以比较 2 个字符串以查看它们是否相等。 我习惯了来自 C++ 的 == 但我了解到,如果你将一个对象与一个字符串进行比较,那么 == 默认为引
我有一个 Point 类和一个 MinesweeperSquare 类,后者是前者的子类。如果我重写后者的 equals 方法,就像这样: if (!(obj instanceof Minesweep
我想知道,如果我们有 if-else 条件,那么检查什么在计算上更有效:使用等于运算符或不等于给运营商?有什么区别吗? 例如,以下哪一项在计算上是高效的,下面的两种情况都会做同样的事情,但哪一种更好(
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
某些框架(例如 guice )在某些情况下需要创建 注解接口(interface)的实现类 . 好像有一个区别 Annotation.equals(Object) 之间和 Object.equals(
从三个变量开始,都是System.DateTime。 a: 10/2/2009 2:30:00 PM b: 10/2/2009 2:30:00 PM c: 10/2/2009 2:30:00 PM 相
我实现了一个 PagedModel 类来包装 IEnumerable,为我的 MVC 应用程序中的网格提供分页数据。我使用 Resharper 自动生成的 Equality 代码告诉它检查数据、总行数
正如问题所述。理想情况下,答案应该是 false,因为它将使用 Object#equal,这只是引用比较。 String cat = new String("cat"); String
我想知道以下两个选项中哪一个在速度方面最有效。它们之间可能只有很小的区别(或者根本没有区别?)但是由于我每天使用该代码片段 30 次,所以我想知道这里的“最佳实践”是什么 :) 选项 1: if (s
我有一个以年龄和姓名作为实例成员的基类,以及带有奖金的派生类。我在派生类中重写 equals 。我知道 Java 中只有一个基类时 equals 是如何工作的。但我无法理解继承的情况下它是如何工作的。
==之间的区别和 ===是前者仅检查值(1 == "1" 将返回 true),后者是否检查值并另外检查类型(1 === "1" 将返回 false,因为 number 不是字符串)。 比较对象意味着比
这是一个理论问题。我有一个我自己设计的对象,其中包含一堆变量、方法等。我覆盖了 toString 方法,主要用于记录目的,以返回变量的值。在我看来,比较此对象实例的最简单和最直接的方法是比较从 toS
我是 Java 编程的初学者。目前我正在 this 阅读关于继承和 equals 方法的内容。页。到目前为止,我理解解释: Compare the classes of this and otherO
当 IntelliJ 建议我更正以下内容时,我正在编写代码: objectOne.equals(objectTwo); 告诉我方法调用 equals 可能会产生旧的 java.lang.NullPoi
我尝试创建一个允许在 Java 中使用类似元组的结构的元组类。元组中两个元素的一般类型分别是 X 和 Y。我尝试为此类覆盖正确的等号。 事情是,我知道 Object.equals 属于默认值,它仍然根
可以用和比较字符串类似的方式来比较序列。如果两个序列的长度相同,并且对应元素都相等,equal() 算法会返回 true。有 4 个版本的 equal() 算法,其中两个用 == 运算符来比较元素,另
我是一名优秀的程序员,十分优秀!