866 votes

Comment vérifier si une variable "lateinit" a été initialisée ?

Je me demande s'il existe un moyen de vérifier si un lateinit a été initialisée. Par exemple :

class Foo() {

    private lateinit var myFile: File

    fun bar(path: String?) {
        path?.let { myFile = File(it) }
    }

    fun bar2() {
        myFile.whateverMethod()
        // May crash since I don't know whether myFile has been initialized
    }
}

3 votes

Ce qu'il vous faut peut-être, c'est rendre la propriété nullable (changer le type en File? ) et vérifier si elle est nulle à la place ?

1 votes

J'ai essayé et cela va fonctionner, mais je vais devoir modifier le fichier allSeries var to seriesDir?.listFiles()?.map { it.name }?.toTypedArray() ce qui n'est pas très "joli"

1 votes

Vous pouvez effectuer une simple vérification de la nullité et le smart cast rendra le tout plus joli. if (seriesDir != null) { allSeries = seriesDir.listFiles().map { it.name }.toTypedArray() }

1692voto

xsveda Points 4408

Il existe un lateinit dans Kotlin 1.2 qui permet de vérifier l'état d'initialisation de lateinit directement :

lateinit var file: File    

if (this::file.isInitialized) { ... }

Voir l'annonce sur Le blog de JetBrains ou le Proposition de GARDER .

UPDATE : La version 1.2 de Kotlin a été publiée. Vous pouvez trouver lateinit Améliorations ici :

3 votes

@fer.marino : Eh bien, Kotlin 1.2 vous permet en fait d'utiliser lateinit également pour les variables locales, voir kotlinlang.org/docs/reference/

0 votes

Ça ne marche pas pour moi. J'obtiens "lateinit property has not been initialized" même après l'avoir utilisé.

11 votes

This::lateinitVar.isInitialized

181voto

Nikhil Katekhaye Points 331

Utilisation .isInitialized permet de vérifier l'état d'initialisation d'une variable lateinit.

if (::file.isInitialized) {
    // File is initialized
} else {
    // File is not initialized
}

106voto

Suraj Vaishnav Points 1445

Vous pouvez facilement le faire :

::variableName.isInitialized

ou

this::variableName.isInitialized

Mais si vous êtes à l'intérieur d'un auditeur ou d'une classe interne, faites ceci :

this@OuterClassName::variableName.isInitialized

Note : Les déclarations ci-dessus fonctionnent bien si vous les écrivez dans le même fichier (même classe ou classe interne) que celui où la variable est déclarée, mais cela ne fonctionnera pas. si vous voulez vérifier la variable d'une autre classe (qui peut être une superclasse ou toute autre classe instanciée) par exemple :

class Test {
    lateinit var str:String
}

Et de vérifier si str est initialisé :

enter image description here

Ce que nous faisons ici : vérification isInitialized pour le champ str de Test dans la classe Test2 classe. Et nous obtenons une erreur en soutenant le champ de var n'est pas accessible à ce stade. Vérifier un question déjà soulevées à ce sujet.

48voto

Kiskae Points 11240

Essayez de l'utiliser et vous recevrez un UninitializedPropertyAccessException s'il n'est pas initialisé.

lateinit est spécifiquement destiné aux cas où les champs sont initialisés après la construction, mais avant l'utilisation réelle (un modèle que la plupart des frameworks d'injection utilisent). Si ce n'est pas votre cas d'utilisation lateinit n'est peut-être pas le bon choix.

EDIT : En fonction de ce que vous voulez faire, quelque chose comme ceci fonctionnerait mieux :

val chosenFile = SimpleObjectProperty<File?>
val button: Button

// Disables the button if chosenFile.get() is null
button.disableProperty.bind(chosenFile.isNull())

0 votes

J'ai une application JavaFX, et j'ai un bouton qui sera toujours désactivé à moins qu'une variable (qui est lateinit ) a été initialisé. En d'autres termes, je veux que le bouton soit désactivé : Je veux que le bouton soit désactivé tant que la variable n'a pas été initialisée. Existe-t-il une bonne façon de procéder ?

0 votes

@MathewHany Comment l'initialisation se ferait-elle normalement ? Vous voudrez peut-être examiner les getter/setters de propriété et une propriété SimpleBoolean que vous pouvez lier à la propriété disabled du bouton.

1 votes

Pour être plus précis, j'ai une application simple qui contient 4 boutons, le premier bouton ouvrira une boîte de dialogue DirectoryChooser, et les 3 autres seront désactivés, lorsque l'utilisateur choisira un répertoire, tous les autres boutons seront disponibles pour l'utilisateur.

31voto

Max Points 6217

Si vous avez un lateinit dans une classe et doit vérifier si elle est initialisée à partir d'une autre classe

if(foo::file.isInitialized) // this wouldn't work

La solution que j'ai trouvée consiste à créer une fonction pour vérifier si la propriété est initialisée et à appeler cette fonction à partir de n'importe quelle autre classe.

Ejemplo:

class Foo() {

    private lateinit var myFile: File

    fun isFileInitialised() = ::file.isInitialized
}

 // in another class
class Bar() {

    val foo = Foo()

    if(foo.isFileInitialised()) // this should work
}

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