14
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Kotlinのdata classを安全に使いたい

Posted at

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らしく書ける。。。

参考

14
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?