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)
}
Kotlin 1.2にはlateinit
の改良があり、lateinit
変数の初期化状態を直接チェックすることができます。
lateinit var file: File
if (::file.isInitialized) { ... }
JetBrainsブログ または KEEPプロポーザル の発表を参照してください。
更新: Kotlin 1.2がリリースされました。 lateinit
の機能強化はここにあります。
それを使用しようとすると、初期化されていない場合はUninitializedPropertyAccessException
を受け取ります。
lateinit
は特に、構築後で実際の使用前にフィールドが初期化される場合のためのものです(ほとんどのインジェクションフレームワークが使用するモデル)。これがあなたのユースケースではない場合、lateinit
は正しい選択ではないかもしれません。
編集:このような何かをやりたいことに基づいてよりうまくいくでしょう:
val chosenFile = SimpleObjectProperty<File?>
val button: Button
// Disables the button if chosenFile.get() is null
button.disableProperty.bind(chosenFile.isNull())
.isInitialized
プロパティを使用して、lateinit変数の初期化状態を確認できます。
if(::file.isInitialized){
//File is initialized
}else{
//File is not initialized
}
kotlin.UninitializedPropertyAccessException: lateinit property clientKeypair has not been initialized
バイトコードは...何とか...
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は同じインスタンスの追加のローカル変数を作成し、nullかどうかをチェックします。nullの場合は 'throwUninitializedPropertyAccessException'をスローし、そうでない場合はローカルオブジェクトを返します。上記のバイトコードの説明 here 解決策kotlin 1.2以降では、lateyinit varが初期化されているか、.isInitialized
を使用していないかを確認できます。
承認された回答Kotlin 1.3+
でコンパイラエラーが発生します。::
の前にthis
キーワードを明示的に指定する必要がありました。以下は作業コードです。
lateinit var file: File
if (this::file.isInitialized) {
// file is not null
}
lateinit var
が初期化されているかどうかを確認するには、そのプロパティへの参照に.isInitialized
を使用します。
if (foo::bar.isInitialized) {
println(foo.bar)
}
このチェックは、字句的にアクセス可能なプロパティ、つまり同じ型または外部型の1つで宣言されているプロパティ、または同じファイルの最上位レベルで宣言されているプロパティに対してのみ使用できます。