2017-07-11 25 views
2
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) 

2つの非関係データクラス間の比較が行われます。Kotlin:Intrinsics.areEqual無限ループ(スタックオーバーフロー)

メジャーバグ。

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

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

興味深いことに、エラーを投げるクラスとコードを表示できますか? – zsmb13

+0

これは、 'Category'と' Destination'がサイクルに依存する可能性があるためです。 –

+0

@ holi-javaああ、これはある意味では真実だ。 'Category'には' MutableList 'があり、' Destination'には 'Category'があります – Jire

答えて

4

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

あなたの例では主犯はこのサイクルである:Destination

Categoryval destinations: MutableList<Destination> &
val category: Category次の2つのいずれかを移動することで、このサイクルを削除する必要があります主データクラスコンストラクタからの変数。 data class Category(..)はそれのために発生します可変、任意のキーとして使用して安全でないと(それは主コンストラクタの中で、他のデータクラスは、カテゴリを使用して!):

しかし、ずっと大きなsideeffectもありますハッシュベースのコレクション。詳細については、以下を参照してください。データクラスは、純粋なデータのために意図されていることを考えるとAre mutable hashmap keys a dangerous practice?

を、私はdata class Destination(..)val category: Categoryの除去をお勧めします、とList<Destination>読み取り専用にdata class Category(..)val destinations: MutableList<Destination>の種類を変更します。変更後に不変状態を解除するには、Kotlinから安全でないキャストを実行するか、Javaからクラスのインスタンスを作成する必要があります。

宛先のカテゴリを逆参照する必要がある場合(およびハッシュマップ/ -sets/etcのクラスを使用していない場合)は、Destinationを通常のクラスにして、equals/hashCodeを自分で実装するか、プライマリコンストラクタのカテゴリ。これはややこしいことですが、セカンダリコンストラクタで行うことができます:

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