español - kotlin vs java
¿Cómo verificar si se ha inicializado una variable "lateinit"? (6)
Hay una mejora de
lateinit
en Kotlin 1.2 que permite verificar el estado de inicialización de la variable
lateinit
directamente:
lateinit var file: File
if (::file.isInitialized) { ... }
Vea el anuncio en el blog de JetBrains o la propuesta KEEP .
ACTUALIZACIÓN:
Kotlin 1.2 ha sido lanzado.
Puede encontrar mejoras de
lateinit
aquí:
Me pregunto si hay una manera de verificar si se ha inicializado una variable
lateinit
.
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)
}
Intente usarlo y recibirá una
UninitializedPropertyAccessException
si no se inicializa.
lateinit
es específicamente para casos donde los campos se inicializan después de la construcción, pero antes del uso real (un modelo que usan la mayoría de los marcos de inyección).
Si este no es su caso de uso,
lateinit
podría no ser la opción correcta.
EDITAR: según lo que quieras hacer, algo como esto funcionaría mejor:
val chosenFile = SimpleObjectProperty<File?>
val button: Button
// Disables the button if chosenFile.get() is null
button.disableProperty.bind(chosenFile.isNull())
Para verificar si una
lateinit var
se inicializó o no, use un
.isInitialized
en la referencia a esa propiedad:
if (foo::bar.isInitialized) {
println(foo.bar)
}
Esta comprobación solo está disponible para las propiedades que son accesibles léxicamente, es decir, declaradas en el mismo tipo o en uno de los tipos externos, o en el nivel superior en el mismo archivo.
Usando la propiedad
.isInitialized
, se puede verificar el estado de inicialización de una variable lateinit.
if(::file.isInitialized){
//File is initialized
}else{
//File is not initialized
}
La respuesta aceptada
me da un error de compilación en
Kotlin 1.3+
, tuve que mencionar explícitamente
this
palabra clave antes de
::
.
A continuación se muestra el código de trabajo.
lateinit var file: File
if (this::file.isInitialized) {
// file is not null
}
kotlin.UninitializedPropertyAccessException: lateinit property clientKeypair has not been initialized
Bytecode dice ... 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 crea una variable local adicional de la misma instancia y comprueba si es nula o no, si es nula, arroja ''throwUninitializedPropertyAccessException'' o devuelve el objeto local.
El bytecode anterior se explica
here
Solución Dado que kotlin 1.2 permite verificar el clima, lateinit var se ha inicializado o no se está utilizando
.isInitialized