Ebn Zhang
Ebn Zhang

Reputation: 251

Kotlin initialize a variable before its declaration?

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...

Upvotes: 19

Views: 4450

Answers (3)

K F
K F

Reputation: 1546

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

Upvotes: 2

smt
smt

Reputation: 89

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.

Upvotes: 1

Mikhail Glukhikh
Mikhail Glukhikh

Reputation: 26

Your example looks like minor inconsistency. It's provoked by a fact the first example has no primary constructor, but the second has one. However, https://youtrack.jetbrains.com/issue/KT-22317 was created.

Upvotes: 0

Related Questions