Search code examples
kotlinstack-overflow

stackoverflowerror in Kotlin


I'm new to kotlin and I have a problem with code: I don't know why exactly when I create an instance of a class it gives me a stackoverflow error

Here is the code :

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")

}

Solution

  • This is because You're creating a new instance of your Spice() class whenever you call

    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"))
    

    What's happening is that at runtime the first line that will execute is the init block so you'll print.

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

    then when you you're past the init you move on to evaluating

    val spiceList = listOf(....)
    

    in Kotlin, assignments are resolved at runtime meaning, even though you're not using spiceList, you're still creating it at that line, along with all the other Spice() objects inside it.

    You'll notice that before you get the stackoverflow, you actually print

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

    Because you're instantiating Spices within Spices, you'll always be stuck in that loop.

    You could move your list to a companion object, which would be treated like a static is in Java, and that way it won't be resolved whenever you instantiate the Spice class