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

时间:2017-07-11 18:13:47

标签: kotlin stack-overflow intrinsics

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比较。

主要错误。

data class Category(val name: String, val destinations: MutableList<Destination>)

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

2 个答案:

答案 0 :(得分:4)

Data classes in Kotlin are just syntactic sugar for Java POJOs.

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

self.scrollViewForImage.delegate = self self.scrollViewForImage.addSubview(self.imgSelected) self.scrollViewForImage.maximumZoomScale = 2.0 func viewForZooming(in scrollView: UIScrollView) -> UIView? { return self.imgSelected } &amp;
中的

val destinations: MutableList<Destination> Category

中的val category: Category

您必须通过将两个变量中的任何一个移出主数据类构造函数来删除此循环。

但是,还有一个很多更大的副作用:Destination 可变,这将导致它(以及其中使用类别的任何其他数据类& #39; s主要构造函数!)在任何基于散列的集合中用作键是不安全的。有关详细信息,请参阅:Are mutable hashmap keys a dangerous practice?

鉴于数据类适用于纯数据,我建议删除data class Category(..)中的val category: Category,并将data class Destination(..)val destinations: MutableList<Destination>的类型更改为只读{{1} }}。为了在所述更改后中断不可变状态,您必须从Kotlin执行不安全的转换或从Java创建该类的实例。

但是,如果您绝对需要对目标中的类别进行反向引用(并且不在hashmaps / -sets / etc.中使用您的类),您可以将Destination设为常规类并自己实现equals / hashCode,或者将类别移出主要构造函数。这有点棘手,但可以使用辅助构造函数完成:

data class Category(..)

答案 1 :(得分:1)

在我的情况下,我覆盖了equals方法,例如:

override fun equals(other: Any?): Boolean {
        // some code here
        if (other==this)
            return true
       // some code here
    }

等于和==(在Java中)

在Java中,当我们使用equals(例如:str1.equals(str2))时,它会检查两个对象的内容(对于自定义对象,您必须重写equals并检查所有对象的值,否则Object类的{{1} }方法只是比较引用,它与==)相同,但是如果我们使用==(例如:equals)运算符,它将检查两个对象的引用。


==科特林

但是对于kotlin,当我们使用==运算符时,它仅在对象是数据类的对象时才检查对象的内容(数据或变量)。并且==运算符检查常规类的引用。

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


因此,在我覆盖的equals方法中,当equals执行时,它将再次调用other==this方法,这将再次调用eaquals方法并产生无限循环。

因此,要使其正常工作,我们需要将==更改为===(这将检查两个运算符的引用),例如:

eaquals
  

注意: if (other===this) return true .equals相同,直到我们将它们与Float或   双。 ==不同意IEEE 754标准   浮点运算,当比较-0.0时返回false   为0.0,而==和===则返回true

     

您可以查看参考文献here