Kotlinだと先頭にdata
を付けるだけで値を保持するためのクラスが作れる。
data class User(val name: String, val age: Int)
Kotlin / Javaの両方から扱える安全なdata class
を作りたい。
data class (最初の案)
data class SafetyData(
val string: String = "",
val list: List<String>? = null
)
Stringには初期値を設定して、ListはNullableにした。
結論 = Javaから使った時に危険!!
Kotlinから使う時
// 引数なしでインスタンス生成
val safetyData = SafetyData()
// Stringへのアクセス
// 初期値がセットされているので安全
val stringLength = safetyData.string.length
// Listへのアクセス1
// ちょっと長いけど安全
val listSize1 = if (safetyData.list != null) safetyData.list.orEmpty().size else -1
// Listへのアクセス2
// JavaのList<String>にキャストしてアクセスも可能だけどやっぱり長い
val listSize2 = if (safetyData.list != null) (safetyData.list as List<String>).size else -1
// Listへのアクセス3
// 短縮形 普通に書く時はこれ
val listSize3 = safetyData.list?.size ?: -1
// Listへのアクセス(コンパイルエラー)
// 以下のような書き方をすると.sizeの部分でコンパイルエラーにしてくれるので安全
val listSizeNg1 = safetyData.list.size
val listSizeNg2 = if (safetyData.list != null) safetyData.list.size else -1
Javaから使う時
SafetyData safetyData = new SafetyData();
// Stringへのアクセス
// 初期値がセットされているので安全
int stringLength = safetyData.getString().length();
// Listへのアクセス(NPEが発生)
// Javaから使う時はコンパイルエラーにならない。危険!!
int listSize = safetyData.getList().size();
data class (修正版)
data class SafetyData(
val string: String = "",
val list: List<String> = listOf()
)
ListはNullableをやめて空の初期値を入れた。
当たり前だけど、初期値が入っているのでJavaから使ってもNPEは発生しない。
結論
Javaからも使いたい場合はNullableにせず、nullではない初期値を入れておくのが安全。
(´-`).。oO(でも、Nullableを使ったほうがKotlinらしく書ける。。。