web-dev-qa-db-fra.com

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

Je me demande s’il existe un moyen de vérifier si une variable lateinit a été initialisée.

import javafx.application.Application
import javafx.event.EventHandler
import javafx.geometry.Insets
import javafx.geometry.Pos
import javafx.scene.Scene
import javafx.scene.control.Button
import javafx.scene.control.ComboBox
import javafx.scene.layout.VBox
import javafx.stage.DirectoryChooser
import javafx.stage.Stage
import Java.io.File

class SeriesManager() {
    lateinit var seriesDir: File
    val allSeries by lazy {
        seriesDir.listFiles().map { it.name }.toTypedArray()
    }
}

class SeriesManagerUI : Application() {
    override fun start(primaryStage: Stage) {
        val sm = SeriesManager()

        val setSeriesDirBtn = Button("Change all series location").apply {
            onAction = EventHandler {
                sm.seriesDir = DirectoryChooser().apply {
                    title = "Choose all series location"
                }.showDialog(primaryStage)
            }
        }
        val allSeriesList = ComboBox<String>().apply {
            promptText = "Select a series from here"
            isDisable = // I want this to be always true, unless the SeriesManager.seriesDir has been initialized
        }
        val setCurrentEpisodeBtn = Button("Change the current episode")
        val openNextEpisode = Button("Watch the next episode")

        val layout = VBox(
            setSeriesDirBtn,
            allSeriesList,
            setCurrentEpisodeBtn,
            openNextEpisode
        ).apply {
            padding = Insets(15.0)
            spacing = 10.0
            alignment = Pos.CENTER
        }

        primaryStage.apply {
            scene = Scene(layout).apply {
                minWidth = 300.0
                isResizable = false
            }

            title = "Series Manager"
        }.show()
    }
}

fun main(args: Array<String>) {
    Application.launch(SeriesManagerUI::class.Java, *args)
}
282
Mathew Hany

Il y a une amélioration de lateinit dans Kotlin 1.2 qui permet de vérifier directement l'état d'initialisation de la variable lateinit:

lateinit var file: File    

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

Voir l’annonce sur blog JetBrains ou proposition KEEP .

UPDATE: Kotlin 1.2 a été publié. Vous pouvez trouver les améliorations de lateinit ici:

703
xsveda

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 leur utilisation réelle (un modèle utilisé par la plupart des infrastructures d'injection). Si ce n'est pas votre cas d'utilisation, lateinit pourrait ne pas être le bon choix.

EDIT: Basé sur 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())
39
Kiskae

En utilisant la propriété .isInitialized, on peut vérifier l'état d'initialisation d'une variable Lateinit.

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

Pour vérifier si un lateinit var a été initialisé ou non, utilisez un .isInitialized sur la référence à cette propriété:

if (foo::bar.isInitialized) {
    println(foo.bar)
}

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

2
ARGeo
kotlin.UninitializedPropertyAccessException: lateinit property clientKeypair has not been initialized

Bytecode dit ... bla bla ..

public final static synthetic access$getClientKeypair$p(Lcom/takharsh/ecdh/MainActivity;)Ljava/security/KeyPair;

`L0
LINENUMBER 11 L0
ALOAD 0
GETFIELD com/takharsh/ecdh/MainActivity.clientKeypair : Ljava/security/KeyPair;
DUP
IFNONNULL L1
LDC "clientKeypair"
INVOKESTATIC kotlin/jvm/internal/Intrinsics.throwUninitializedPropertyAccessException (Ljava/lang/String;)V
    L1
ARETURN

L2 LOCALVARIABLE $ this Lcom/takharsh/ecdh/MainActivity; L0 L2 0 MAXSTACK = 2 MAXLOCALS = 1

Kotlin crée une variable locale supplémentaire de la même instance et vérifie si elle est nulle ou non. Si cette valeur est null, elle renvoie alors 'throwUninitializedPropertyAccessException', sinon elle renvoie l'objet local. Au-dessus du bytecode expliqué ici Solution Depuis kotlin 1.2, il permet de vérifier si la météo a été initialisée ou si la var a été initialisée ou non avec .isInitialized

0
takharsh

Réponse acceptée me donne une erreur de compilation dans Kotlin 1.3+, je devais mentionner explicitement le mot clé this avant ::. Ci-dessous le code de travail.

lateinit var file: File

if (this::file.isInitialized) {

    // file is not null
}
0