KotlinのlateinitでJavaFXが捗る
*最近*Kotlinに遅延初期化プロパティがあることを知りました。
遅延初期化プロパティはドキュメントから引用すると、
通常、非null型として宣言されたプロパティは、コンストラクタ内で初期化される必要がある。
http://qiita.com/dogwood008/items/6e8d3225ea9bb0fe3099#%E9%81%85%E5%BB%B6%E5%88%9D%E6%9C%9F%E5%8C%96%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3
しかし、これはかなり不便である。例えば、プロパティが依存オブジェクト (dependency injection 訳注:参考)により初期化されたり、ユニットテストのセットアップメソッドで初期化されたり。
この事例では、非nullイニシャライザをコンストラクタ内で提供することができないが、それでもクラス内の本体にあるプロパティを参照する際にnullチェックを避けたいであろう。
このような事例を処理するには、プロパティを lateinit 識別子でマークすることができる
これを使うことで、JavaFXのコンポーネントを非nullとして扱えます。
まず、lateinitを使用しない場合は次のようなコードになります。
class SampleController : Initializable { @FXML var button: Button? = null @FXML var label: Label? = null @FXML fun onActionButton() { label!!.text = "テスト" } public override fun initialize(location: URL?, resources: ResourceBundle?) { } }
コンストラクタ内でButtonオブジェクトを確実に初期化しなければならず、またコンストラクタ実行時の段階では値が定まらないため、null許容型にし、さらに値自体もnullで初期化しなければなりません。そのため、ボタンが押された時のonActionButton
メソッドで、label!!.text = "テスト"
のように!!
をつけてプロパティやメソッドを呼び出す必要がありました。
しかし、lateinit
を使用すると、次のように書くことができます。
class SampleController : Initializable { @FXML lateinit var button: Button @FXML lateinit var label: Label @FXML fun onActionButton() { label.text = "テスト" } public override fun initialize(location: URL?, resources: ResourceBundle?) { } }
このように!!
を使わずにすっきりと書くことができます。