首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Kotlin: Intrinsics.areEqual无限循环(堆栈溢出)

Kotlin: Intrinsics.areEqual无限循环(堆栈溢出)
EN

Stack Overflow用户
提问于 2017-07-11 18:13:46
回答 2查看 1.1K关注 0票数 4
代码语言:javascript
复制
java.lang.StackOverflowError
    at kotlin.jvm.internal.Intrinsics.areEqual(Intrinsics.java:164)
    at plugin.interaction.inter.teleports.Category.equals(Category.kt)
    at kotlin.jvm.internal.Intrinsics.areEqual(Intrinsics.java:164)
    at plugin.interaction.inter.teleports.Destination.equals(Destination.kt)

从两个非关系数据类之间的.equals比较中发生。

大虫子。

代码语言:javascript
复制
data class Category(val name: String, val destinations: MutableList<Destination>)

data class Destination(val category: Category, val name: String)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-07-11 23:53:04

Kotlin中的数据类只是Java的语法糖。

你的例子中的主要罪魁祸首是这个循环:

val destinations: MutableList<Destination> in Category &

val category: Category in Destination

必须将这两个变量中的任何一个移出主数据类构造函数,从而删除此周期。

然而,还有一个更大的副作用:data class Category(..)可变的,这将导致它(以及在它的主构造函数中使用类别的任何其他数据类!)在任何基于散列的集合中用作键是不安全的。有关更多信息,请参见:可变的hashmap键是一种危险的做法吗?

考虑到数据类是用于纯数据的,我建议删除data class Destination(..)中的val destinations: MutableList<Destination>,并将data class Category(..)中的val destinations: MutableList<Destination>类型改为只读List<Destination>。为了打破上述更改后的不可变状态,您必须从Kotlin执行不安全的强制转换,或者从Java创建类的实例。

但是,如果您绝对需要反向引用目的地中的类别(而不是在hashmap/-set/等等中使用您的类),那么您可以将目的地变成一个常规类并自己实现相等/hashCode,或者将这个类别从主构造函数中移出。这有点棘手,但可以使用辅助构造函数来完成:

代码语言:javascript
复制
data class Destination private constructor(val name: String) {
    private lateinit var _category: Category
    val category get() = _category
    constructor(category: Category, name: String) : this(name) {
        _category = category
    }
}
票数 4
EN

Stack Overflow用户

发布于 2019-06-12 05:59:53

在我的例子中,我重写了相等的方法,比如:

代码语言:javascript
复制
override fun equals(other: Any?): Boolean {
        // some code here
        if (other==this)
            return true
       // some code here
    }

=和==在java中的应用

在java中,当我们使用等于(for ex:str1.equals(str2))时,它检查两个对象的内容(对于自定义对象,您必须重写等于并检查对象的所有值,否则对象类的equals方法只是比较引用,这与==相同),但是如果我们使用==(for ex:str1==str2)操作符,它会检查两个对象的引用。

== in kotlin

但是对于kotlin,当我们使用==运算符时,只有当对象是数据类的对象时,它才会检查对象的内容(数据或变量)。==操作符检查正常类的引用。

当我们使用==时,它将调用equals方法。

因此,在我的重写的等于方法中,当other==this执行时,它将再次调用eaquals方法,这将再次调用eaquals方法,并产生一个无限循环。

为了使其工作,我们需要将更改为===(这将检查两个操作符的引用),如下所示:

代码语言:javascript
复制
 if (other===this)
     return true

注意:.equals==是相同的,直到我们将它们与Float或Double一起使用为止。.equals不符合IEEE 754浮点算法标准,当-0.0与0.0比较时,它返回假,而==和===则返回true。 您可以检查引用这里

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45041834

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档