突然ですがクイズです!
fun main() {
println(null?.toString())
}
fun main() {
println(null!!.toString())
}
fun main() {
println(null.toString())
}
それぞれ結果はどうなるでしょうか!
- コンパイルエラー
- NullPointerException
- null
- "null"
- いずれでもない
正解(結果)
null
過去私「うん」
Exception in thread "main" kotlin.KotlinNullPointerException
at MainKt.main(Main.kt:2)
at MainKt.main(Main.kt)
過去私「だよね」
null
過去私「?????(コンパイルエラー、仮に通ってもぬるぽだと思っていた顔)」
まさかと思って以下を実行。
fun main() {
println(null?.toString() is String)
println(null.toString() is String)
}
null.toString()
はコンパイルエラーでもNullPointerExceptionでもなくnullの文字列"null"になる。え、"null"なの...と知った時はびっくりしました(空文字""ならまだわかるけど)。
false
true
そしてこれに関して、公式ドキュメントのtoString()のページにちゃんと書いてありました。
ちゃんと公式ドキュメントは読みましょうね..
Returns a string representation of the object. Can be called with a null receiver, in which case it returns the string "null".
nullableのオブジェクトに対してtoString()をするとnullの文字列が返るのは仕様!
なので?.
をつけ忘れてもコンパイルエラーやIntelliJ上でエラーも出ない。うっかりつけ忘れるとすると意図せぬ結果に出くわすかも...??
val msg: MessageObject? = null
// msg対する何かしらの処理
// 結果としてmsgがnullのままだったとする
// 出力 -> "null"
println(msg.toString() ?: "default message")
?.
をつけてtoString()すれば当然だけど期待する結果が得られる。
val msg: MessageObject? = null
// msg対する何かしらの処理
// 結果としてmsgがnullのままだったとする
// 出力 -> "default message"
println(msg?.toString() ?: "default message")