https://kotlinlang.org logo
Title
j

Jonathan Lennox

05/18/2023, 7:41 PM
In code like the below, Kotlin complains that the fields aren't initialized, even though if I copy the code from
updateFields
into the second constructor it does. Is there a way I can get Kotlin to know the fields are always initialized, without duplicating the code between
updateFields
and the constructor?
class DemoClass
{
    var field1: Int
        private set
    var field2: Int
        private set

    constructor(f1: Int, f2: Int) {
        field1 = f1
        field2 = f2
    }

    constructor(basef: Int) {
        updateFields(basef)
    }

    fun updateFields(basef: Int) {
        field1 = basef * 2
        field2 = basef + 2
    }
}
l

Landry Norris

05/18/2023, 7:50 PM
You can declare a variable as 'lateinit var' to promise the compiler you will initialize it.
h

Haram Kwon

05/18/2023, 7:50 PM
the easiest way to solve this problem is to initialized the number
class DemoClass
{
    var field1: Int = 0
        private set
    var field2: Int = 0
        private set

    constructor(f1: Int, f2: Int) {
        field1 = f1
        field2 = f2
    }

    constructor(basef: Int) {
        updateFields(basef)
    }

    fun updateFields(basef: Int) {
        field1 = basef * 2
        field2 = basef + 2
    }
}
@Landry Norris lateinit may not work for primitive types 😞
j

Jonathan Lennox

05/18/2023, 7:51 PM
So initialize it for primitive or nullable, lateinit for non-nullable objects?
l

Landry Norris

05/18/2023, 7:52 PM
Doesn't it force the primitive to be boxed? Slight performance hit, but should work. Guess it doesn't do this.
j

Jonathan Lennox

05/18/2023, 7:53 PM
It still seems like the compiler should be able to figure that out, though.
As long as the method called isn't open.
h

Haram Kwon

05/18/2023, 8:00 PM
Let me know if you find a better way 🙂
e

ephemient

05/19/2023, 12:59 AM
class DemoClass(field1: Int, field2: Int) {
    var field1 = field1
        private set
    var field2 = field2
        private set

    constructor(basef: Int) : this(
        field1 = basef * 2,
        field2 = basef + 2,
    )
}
j

Jonathan Lennox

05/19/2023, 4:05 AM
@ephemient: This doesn't solve the problem of duplicating the code between the constructor and the update method (the idea is that class also allows the
updateFields
method to be called later to change the values).
e

ephemient

05/19/2023, 4:17 AM
then
class DemoClass(field1: Int, field2: Int) {
    var field1 = field1
        private set
    var field2 = field2
        private set

    constructor(basef: Int) : this(0, 0) {
        updateFields(basef)
    }
}