https://kotlinlang.org logo
#getting-started
Title
# getting-started
e

elye

08/12/2022, 8:36 AM
Probably a newbie question? I have 2 enums that cross-reference each other
Copy code
enum class School(val zone: String, val captain: Student) {
    Metricon("New York", Student.David),
    Carlisle("London", Student.Paul)
}

enum class Student(val lastName: String, val school: School) {
    David("Samuel", School.Metricon),
    Solomon("Handsome", School.Metricon),
    Saul("Black", School.Metricon),
    Paul("Lewis", School.Carlisle),
    Joseph("Hardy", School.Carlisle),
    John("Baptise", School.Carlisle),
}
When I print it out
Copy code
val student = Student.David
        val school = School.Carlisle

        println(student.school)
        println(school.captain)
        println(student.lastName)
        println(school.zone)
It resulted in
Copy code
Metricon
null
Samuel
London
Notice the
null
there. The
school.captain
is missing and became null. How can I solve this problem?
r

Roukanken

08/12/2022, 8:48 AM
I think this is the same problem as:
Copy code
class A() {
    val x: String = initX()
    val y: String = "value"

    fun initX(): String = y
}

A().x     // is null
eg, at the time
x
was "calculated", the
y
was not yet initialized, and was therefore
null
as all objects within JVM before initialization, and therefore is null even though types don't allow that In your case: you first accessed
Student.David
, which started initializing
Student
enum, but to init the first
David
, it needed to access
School.Metricon
so the
School
enum started initializing - but at that point, every other
Student
than
David
is still null
m

Michael de Kaste

08/12/2022, 9:08 AM
The problem is a constructor referenced cycle where like @Roukanken explained. You kinda have to make sure that getting the value in one of the classes is done only when the value is called like so:
Copy code
enum class School(val zone: String) {
    Metricon("New York") {
        override val captain: Student
            get() = Student.David
    },
    Carlisle("London") {
        override val captain: Student
            get() = Student.Paul
    };

    abstract val captain: Student
}
j

Joffrey

08/12/2022, 10:28 AM
That said, it would be interesting to know why the student class is an enum. What is your real world use case?