constructor in Kotlin

A class in Kotlin can have a primary constructor and one or more secondary constructors. The primary constructor is part of the class header: it goes after the class name (and optional type parameters).
```
class Person constructor(firstName: String) { /*...*/ }
```
If the primary constructor does not have any annotations or visibility modifiers, the constructor keyword can be omitted:
```
class Person(firstName: String) { /*...*/ }
```
The primary constructor cannot contain any code. Initialization code can be placed in initializer blocks, which are prefixed with the init keyword.
During an instance initialization, the initializer blocks are executed in the same order as they appear in the class body, interleaved with the property initializers:
```
class InitOrderDemo(name: String) {
    val firstProperty = "First property: $name".also(::println)
    init {
        println("First initializer block that prints ${name}")
    }
    val secondProperty = "Second property: ${name.length}".also(::println)
    init {
        println("Second initializer block that prints ${name.length}")
    }
}
```
Note that parameters of the primary constructor can be used in the initializer blocks. They can also be used in property initializers declared in the class body:
```
class Customer(name: String) {
    val customerKey = name.toUpperCase()
}
```
In fact, for declaring properties and initializing them from the primary constructor, Kotlin has a concise syntax:
```
class Person(val firstName: String, val lastName: String, var age: Int) { /*...*/ }
```
You can use a trailing comma when you declare class properties:
```
class Person(
    val firstName: String,
    val lastName: String,
    var age: Int, // trailing comma
) { /*...*/ }
```
Much the same way as regular properties, the properties declared in the primary constructor can be mutable (var) or read-only (val).
If the constructor has annotations or visibility modifiers, the constructor keyword is required, and the modifiers go before it:
```
class Customer public @Inject constructor(name: String) { /*...*/ }
```
The class can also declare secondary constructors, which are prefixed with constructor:
```
class Person {
    var children: MutableList<Person> = mutableListOf()
    constructor(parent: Person) {
        parent.children.add(this)
    }
}
```
If the class has a primary constructor, each secondary constructor needs to delegate to the primary constructor, either directly or indirectly through another secondary constructor(s). Delegation to another constructor of the same class is done using the this keyword:
```
class Person(val name: String) {
    var children: MutableList<Person> = mutableListOf()
    constructor(name: String, parent: Person) : this(name) {
        parent.children.add(this)
    }
}
```
Note that code in initializer blocks effectively becomes part of the primary constructor. Delegation to the primary constructor happens as the first statement of a secondary constructor, so the code in all initializer blocks and property initializers is executed before the secondary constructor body. Even if the class has no primary constructor, the delegation still happens implicitly, and the initializer blocks are still executed:
```
class Constructors {
    init {
        println("Init block")
    }
    constructor(i: Int) {
        println("Constructor")
    }
}
```
If a non-abstract class does not declare any constructors (primary or secondary), it will have a generated primary constructor with no arguments. The visibility of the constructor will be public. If you do not want your class to have a public constructor, you need to declare an empty primary constructor with non-default visibility:
```
class DontCreateMe private constructor () { /*...*/ }
```
NOTE: On the JVM, if all of the parameters of the primary constructor have default values, the compiler will generate an additional parameterless constructor which will use the default values. This makes it easier to use Kotlin with libraries such as Jackson or JPA that create class instances through parameterless constructors.
```
    class Customer(val customerName: String = "")
```