Reputation: 25
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")
}
Upvotes: 1
Views: 2313
Reputation: 370
Here is your mistake:
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"))
you are creating list of spices in each instance, and each Spice item in the list is creating list of spices and so on, then you will face a burst!. you could use a sealed class for this situation, or just use companion object to make it as a static list.
Upvotes: 0
Reputation: 3349
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
Upvotes: 3
Reputation: 8481
It's because of spiceList
field: every instance of Spice
will try to initialize this field and hence create a list of Spice
s, each of which will create a new list and so on.
You could move spiceList
to a companion object to make it tied to a class rather than to instances of it.
Upvotes: 6