web-dev-qa-db-fra.com

Kotlin initialise-t-il une variable avant sa déclaration?

Voici mon code de test:

class Test {
    init {
        a = 1
    }

    constructor() {
        a = 2
    }

    private var a: Int

    init {
        a = 3
    }
}

Si je supprime le constructeur secondaire:

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

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

    private var a: Int

    init {
        a = 3
    }
}

Je le sais

Lors de l'initialisation d'une instance, les blocs d'initialisation sont exécutés dans le même ordre où ils apparaissent dans le corps de la classe.

Mais pourquoi puis-je initialiser la variable avant sa déclaration s'il existe un constructeur secondaire?


Mettre à jour:

Et j'ai trouvé une chose intéressante:

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

La sortie est: 1 0 3 2, c'est la même chose que Java, déclaration et initialisation sont deux étapes différentes, mais c'est bizarre pour le constructeur principal de Kotlin, Er ...

18
Ebn Zhang

De mon point de vue, il ne s'agit pas de kotlin, mais du bytecode de la machine virtuelle Java qui n'a pas réellement d'initialisation de variables; il les remplit simplement dans le constructeur. Vous pouvez l'inspecter avec un décompilateur.

1
smt

Ceci est en train de s'étendre du commentaire de Michael qui fait référence à la documentation Kotlin :

Notez que le code dans les blocs d'initialisation devient effectivement une partie du constructeur principal. La délégation au constructeur primary est la première instruction d'un constructeur secondaire. Le code de tous les blocs d'initialisation est donc exécuté avant le corps du constructeur secondaire. Même si la classe n'a pas de constructeur principal, la délégation se produit toujours de manière implicite et les blocs d'initialisation sont toujours exécutés.

En d'autres termes, les blocs init() sont associés au constructeur primaire (implicite), qui est exécuté en tant que première ligne de votre constructeur secondaire. -Kf

1
K F

Votre exemple ressemble à une incohérence mineure. Cela est provoqué par un fait, le premier exemple n'a pas de constructeur primaire, mais le second en a un. Cependant, https://youtrack.jetbrains.com/issue/KT-22317 a été créé.

0
Mikhail Glukhikh