This error is telling you that there is at least one way to construct instances of your class without initializing the _age property.
The secondary constructor always delegates to the primary constructor, but not the other way around. This means, as @gidds pointed out, that if someone calls the primary constructor directly, the property _age will never get a chance to be initialized, hence your error here:
val person = Person("John", "Doe") // what would _age be here?
It's usually easier to make the primary constructor deal with all the state that you need, and provide either arguments with default values or secondary constructors if you want optional ways to construct instances without all the information.
In your case, you don't really need a secondary constructor at all here, you should just need default values for your primary constructor arguments.
Also, you can use a shorter syntax for your primary constructor, which allows you to declare its arguments and define properties of your class at the same time:
class Person(
val firstname: String,
val lastname: String,
val age: Int = 25, // whichever default you want here
) {
init {
println("The name of the person is $firstname")
println("The age of $firstname $lastname is $age")
}
}
The above is quite compact, and defines the following:
- a primary constructor with arguments
firstname, lastname and age, where age is an optional argument with a default value
- 3 read-only properties (because of
val) on your class, which have the same names as the primary constructor arguments
When the constructor is called, the properties are automatically initialized with the values of the constructor argument, and then the init block is executed.
Side notes:
- avoid
var as much as possible, prefer read-only vals instead. They are easier to reason about, for humans and for the compiler, which can do better smart casts and optimizations
- avoid the
_ prefix in general, and especially in public property (this is not very standard Kotlin style)