Here is my test code:
class Test {
init {
a = 1
}
constructor() {
a = 2
}
private var a: Int
init {
a = 3
}
}
If I remove the secondary constructor:
class Test {
init {
a = 1 // Error: Variable cannot be initialized before declaration
}
// constructor() {
// a = 2
// }
private var a: Int
init {
a = 3
}
}
I know that
During an instance initialization, the initializer blocks are executed in the same order as they appear in the class body.
But why can I initialize the variable before its declaration if there is a secondary constructor?
Update:
And I found an interesting thing:
class Test {
init {
a = log(1)
}
constructor() {
a = log(2)
}
private var a: Int = log(0)
init {
a = log(3)
}
}
fun log(i: Int): Int {
println(i)
return i
}
fun main(args: Array<String>) {
Test()
}
The output is: 1 0 3 2
, this is same as Java, declaration and initialization are two different step, but that is weird for Kotlin's primary constructor, Er...
Every variable must be declared, indicating its data type, before it can be used. Declaration can also involve explicit initialization, giving the variable a value; a variable that is declared but not explicitly initialized is of uncertain value (and should be regarded as dangerous until it is initialized).
To initialize a String variable in Kotlin, we may assign the String literal to the variable without specifying explicit type, or we may declare a variable of type String and assign a String literal later.
Local variables must be initialized before use, as they don't have a default value and the compiler won't let us use an uninitialized value.
In certain computer programming languages, the Elvis operator ?: is a binary operator that returns its first operand if that operand is true , and otherwise evaluates and returns its second operand.
This is expanding from Michael's comment which refers to the Kotlin documentation:
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 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.
In other words, the init()
blocks get associated to the (implicit) primary constructor, which is executed as the first line of your secondary constructor. -Kf
From my point of view it relates not to kotlin but to JVM bytecode which does not actually has "initialization" of variables it just fills them up in constructor, you can inspect it with some decompiler.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With