How do I initialize a val member in a secondary constructor?

I have multiple vals that I need to calculate based on input in one constructor, but which may be previously calculated and provided as arguments to another constructor. I can’t have either constructor be primary because I can’t calculate them all in one line. How do I initialize vals in the body of secondary constructors?

Example please :wink:

You can’t define property in a secondary constructor that are nod defined in a primary once. Because otherwise it would be undefined for the primary constructor. In Java you can always leave it undefined and therefore null or default primitive value. In kotlin it is prohibited due to null safety. So either you define the property in the main constructor and call it from the secondary constructor, or (the better way) you redesign your code to avoid secondary constructor altogether.

@darksnake I can redesign to use static or companion object factory methods. Some people say that’s good practice anyway, but IMO either everything should be factory methods or nothing, and it can’t realistically be everything without redesigning the language itself.
It seems like I just have to make members that really should be vals nullable vars instead so that they can be null until initialized. So I have to choose between null safety and immutability.

It works just like you’d expect if you don’t have a primary constructor.

class Foo {
    val x: String
    constructor (x: String) { this.x = x } 
    constructor (i: Int) { x = i.toString() } 
}

Private functions defined in the file or companion scope can be used to calculate values to pass to another constructor.

2 Likes