wake-up-neo.net

Kotlin initialisiert eine Variable vor ihrer Deklaration?

Hier ist mein Testcode:

class Test {
    init {
        a = 1
    }

    constructor() {
        a = 2
    }

    private var a: Int

    init {
        a = 3
    }
}

Wenn ich den sekundären Konstruktor entferne:

class Test {
    init {
        a = 1 // Error: Variable cannot be initialized before declaration
    }

//    constructor() {
//        a = 2
//    }

    private var a: Int

    init {
        a = 3
    }
}

Ich weiß das

Während einer Instanzinitialisierung werden die Initialisierungsblöcke in der gleichen Reihenfolge ausgeführt, in der sie im Klassenhauptteil angezeigt werden.

Aber warum kann ich die Variable vor ihrer Deklaration initialisieren, wenn es einen sekundären Konstruktor gibt?


Aktualisieren:

Und ich habe eine interessante Sache gefunden:

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()
}

Die Ausgabe ist: 1 0 3 2, dies ist das gleiche wie Java, Deklaration und Initialisierung sind zwei verschiedene Schritte, aber das ist für Kotlins primären Konstruktor Er ...

18
Ebn Zhang

Aus meiner Sicht bezieht es sich nicht auf Kotlin, sondern auf JVM-Bytecode, der eigentlich keine "Initialisierung" von Variablen hat. Er füllt sie nur im Konstruktor auf. Sie können ihn mit einem Decompiler untersuchen.

1
smt

Dies erweitert sich aus Michaels Kommentar, der sich auf die Kotlin-Dokumentation bezieht :

Beachten Sie, dass der Code in Initialisierungsblöcken tatsächlich Teil des primären Konstruktors wird. Die Delegierung an den primary-Konstruktor erfolgt als erste Anweisung eines sekundären Konstruktors, sodass der Code in allen Initialisierungsblöcken vor dem sekundären Konstruktorkörper ausgeführt wird. Selbst wenn die Klasse keinen primären Konstruktor hat, erfolgt die Delegierung immer noch implizit, und die Initialisierungsblöcke werden weiterhin ausgeführt.

Mit anderen Worten, die init()-Blöcke werden dem (impliziten) primären Konstruktor zugeordnet, der als erste Zeile des sekundären Konstruktors ausgeführt wird. -Kf

1
K F

Ihr Beispiel sieht nach einer geringfügigen Inkonsistenz aus. Es wird durch eine Tatsache hervorgerufen, dass das erste Beispiel keinen primären Konstruktor hat, das zweite jedoch einen. https://youtrack.jetbrains.com/issue/KT-22317 wurde jedoch erstellt.

0