Kotlin 中的 stackoverflowerror

stackoverflowerror in Kotlin

我是 kotlin 的新手,我的代码有问题:我不知道为什么当我创建一个 class 的实例时它给我一个 Whosebug 错误

代码如下:

class Spice(val spiceName: String,val spiciness: String = "mild") {

    init {
        println("[$spiceName - $spiciness] ")
    }

    val spiceList: List<Spice> = listOf(
            Spice("curry", "mild"),
            Spice("pepper", "medium"),
            Spice("cayenne", "spicy"),
            Spice("ginger", "mild"),
            Spice("red curry", "medium"),
            Spice("green curry", "mild"),
            Spice("hot pepper", "extremely spicy"))

    val heat: Int
        get() {
            return when (spiciness) {
                "mild" -> 1
                "medium" -> 3
                "spicy" -> 5
                "very spicy" -> 7
                "extremely spicy" -> 10
                else -> 0
            }
        }


    fun makeSalt() = Spice("Salt")

}

这是因为 spiceList 字段:Spice 的每个实例都将尝试初始化该字段并因此创建一个 Spice 的列表,每个都将创建一个新列表等等。

您可以将 spiceList 移动到 companion object 以使其绑定到 class 而不是它的实例。

这是因为您在每次调用

时都在创建 Spice() class 的新实例
val spiceList: List<Spice> = listOf(
  Spice("curry", "mild"),
  Spice("pepper", "medium"),
  Spice("cayenne", "spicy"),
  Spice("ginger", "mild"),
  Spice("red curry", "medium"),
  Spice("green curry", "mild"),
  Spice("hot pepper", "extremely spicy"))

发生的事情是在运行时将执行的第一行是 init 块,因此您将打印。

[Whatever you passed in for your first param, "mild"]

然后,当您通过 init 时,您将继续评估

val spiceList = listOf(....)

在 Kotlin 中,赋值在 运行时 意味着,即使你没有使用 spiceList,你仍然在该行创建它,以及其中的所有其他 Spice() 个对象。

您会注意到,在获取 Whosebug 之前,您实际上打印了

[Whatever you passed in for your first param, "mild"]
["curry", "mild"] x thousands of times

因为您在 Spices 中实例化 Spices,所以您将始终陷入该循环。

您可以将您的列表移动到伴生对象,这将被视为 Java 中的静态对象,这样它就不会在您实例化 Spice 时被解析 class

这是你的错误:

val spiceList: List<Spice> = listOf(
Spice("curry", "mild"),
Spice("pepper", "medium"),
Spice("cayenne", "spicy"),
Spice("ginger", "mild"),
Spice("red curry", "medium"),
Spice("green curry", "mild"),
Spice("hot pepper", "extremely spicy"))

你在每个实例中创建香料列表,列表中的每个香料项目都在创建香料列表等等,然后你将面临爆发!。 对于这种情况,您可以使用密封的 class,或者只使用伴随对象将其作为静态列表。