83 votes

isInitialized - Le champ arrière de la var lateinit n'est pas accessible à ce stade.

J'essaie de vérifier si un lateinit a été initialisée.
Dans Kotlin 1.2, nous disposons désormais de la fonction isInitialized pour cela. Cela fonctionne lorsque je fais cela dans la classe où la propriété lateinit est déclarée. Mais lorsque j'essaie d'appeler cette méthode depuis une autre classe, j'obtiens l'avertissement suivant :

Le champ de sauvegarde de 'lateinit var foo : Bar' n'est pas accessible à ce stade

Ma classe modèle (disons Person ) est écrit en Java
Deux autres classes (disons Test1 y Test2 ) sont écrits en Kotlin

Exemple :

class Test1 {
    lateinit var person: Person

    fun method() {
        if (::person.isInitialized) {
            // This works
        }
    }
}

-

class Test2 {
    lateinit var test1: Test1

    fun method() {
        if (test1::person.isInitialized) {
            // Error
        }
    }
}

Y a-t-il une chance que cela fonctionne ?

Ma solution actuelle consiste à créer une méthode dans Test1 qui renvoie les résultats suivants isInitialized de la person propriété.

fun isPersonInitialized(): Boolean = ::person.isInitialized

//in Test2:
if (test1.isPersonInitialized()) {
    // Works
}

0 votes

Je ne connais pas la réponse. Mais pourquoi vous utilisez isInitialized sur nullable ? lateinit doivent toujours être initialisés avant l'objet utilisé.

0 votes

@Eledgy votre code ne compile pas. vous ne pouvez pas mettre une expression if directement dans le corps d'une classe. je pense que vous avez oublié de l'envelopper dans un bloc init. je sais, cela ne résout pas votre problème initial.

0 votes

Joshua, j'ai un cas où la personne n'est pas encore initialisée.

106voto

AutonomousApps Points 2074

Une solution de contournement très simple aux contraintes décrites par l'initiative réponse acceptée est le suivant :

class LateClass {
    lateinit var thing: Thing
    fun isThingInitialized() = ::thing.isInitialized
}

class Client {
    val lateClass = LateClass()
    ... things happen ...
    if (lateClass.isThingInitialized() {
        // do stuff with lateClass.thing, safely
    }
}

3 votes

Très joli et élégant. converti en propriété val isThingInitialized : Booléen = ::thing.isInitialized

1 votes

@TejasviHegde isThingInitialized ne sera-t-il pas défini à false lors de la création et ne sera-t-il pas mis à jour à true une fois que la chose est initialisée étant donné qu'elle est immuable ?

0 votes

@ThomasSunderland isThingInitialized n'est pas immuable, c'est une fonction.

34voto

Raghav Points 1068

Selon le docs :

Cette vérification n'est disponible que pour les propriétés qui sont lexicalement accessibles, c'est-à-dire déclarées dans le même type ou dans l'un des types externes, ou au niveau supérieur dans le même fichier.

C'est pourquoi vous ne pouvez pas le vérifier dans la fonction principale.

4 votes

Cela doit encore être envisagé pour la version 1.3.+ de kotlin :)

19voto

Sattar Hummatli Points 689

Ma version en tant que propriété Kotlin.

class LateClass {
    lateinit var thing: Thing
    val isThingInitialized get() = this::thing.isInitialized 
}

0voto

Willi Mentzel Points 7681

Vous pouvez vérifier si un lateinit a été initialisée en attrapant le UninitializedPropertyAccessException comme ça :

class Person {
    lateinit var name: String
}

class Test {
    lateinit var person1: Person
    lateinit var person2: Person

    init {
        try {
            println(person1.name)
        }
        catch(e: UninitializedPropertyAccessException) { // is thrown because person1 has not been initialized
            println("ups")
        }

        person2 = Person()

        try {
            println(person2.name)
        }
        catch(e: UninitializedPropertyAccessException) { // is thrown because person2.name has not been initialized
            println("ups")
        }
    }
}

fun main(args: Array<String>) {
   Test() // ups ups
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X