Help us understand the problem. What is going on with this article?

KotlinのNull Safety攻略ガイド

Null Safetyって何?

Null Safety = 変数がNullの場合に安全に処理を行ってくれる
もう少し端的に述べるとNullPointerExceptionを防いでくれる
Java経験がある方なら一度は経験したことのあるNullPointerException。
nullのメンバにアクセスしようとする際にNullPointerExceptionが生じ、アプリをクラッシュさせてしまう。
Null Safetyはこの事象を防ぐことを目的としている。

Non-NullとNullable

kotlinの変数の型にはNon-NullとNullableの2種類が存在する。

  • Non-Null:null代入されない想定の型(null非許容)
  • Nullable:nullが代入される想定の型(null許容)

上記のように、簡単に述べるとnullが代入できるかできないかの違いとなる。
実際にコードに記述する際はどうなるのか?

class MainActivity: AppCompatActivity() {
  //kotlinでnullを非許容するとする型宣言(Non-Null)
  var non_null_text: String = ""

  //kotlinでnullを許容する型宣言(Nullable)
  var nullable_text: String? = ""

  override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //コンパイルエラー
        non_null_text = null
        //nullが代入される
        nullable_text = null
    }
}

一般的なkotlinの型宣言はnon_null_textのような形になると思うが、これだとnullは許容してくれない。
そのため、nullable_textのように型名の後に?をつけて宣言を行うことでnullを許容してくれるようになる。

Safe Callsと!! Operator

nullが入ってもいいようにString?で型宣言も行い、試しにnullable_text.lengthでも実行してみようと思ったが、エラーが生じてしまった。
エラー内容はonly safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?となっている。
冒頭でも述べたが、これはnullのメンバにアクセスすることでNullPointerExceptionが生じてしまうことを示している。
エラーの解決策としては、内容にも書かれているように?.!!.をつければいい。
ただし、この2つは意味合いはまったく異なるものであることは理解しておいて欲しい。
コードの記述方法は2つとも似ている。

val length1 = nullable_text?.length
val length2 = nullable_text!!.length

上記の記述でコンパイルエラーはなくなる。
nullable_textがnullだった場合に、2つがどのような挙動をするのかというと、length1では処理が通るが、length2ではNullPointerExceptionが生じ、クラッシュしてしまう

  • ?.(Safe calls)

?.を使用すると、もし変数がnullでなければそのまま処理を行うが、変数がnullの場合は処理を行わずにnullを返すようになる。
そのため、アプリがクラッシュするようなことはなくなる。

  • !!.(!! Operator)

!!.を使用すると、もし変数がnullでなければそのまま処理を行うが、変数がnullの場合はNullPointerExceptionを返すようになる。
そのため、アプリがクラッシュする。

上記のような違いがあるので、使い分けは慎重に、特に!!.は気をつけて使用する必要がありそう。

エルビス演算子

?.を用いてnullable_text?.lengthが使用できるようになったが、nullable_textがnullの時は空文字を代入したい...
そのような時に役立つのがエルビス演算子?:になる。

//nullable_textがnullの場合、length1にはnullが代入されてしまう
val length1 = nullable_text?.length
//nullable_textがnullの場合、length2には""(空文字)が代入される
val length2 = nullable_text?.length ?: "

エルビス演算子は、?:より左側の処理がnullでないのであればそのまま処理を行い、nullであるのならば?:より右側の処理を行う。
ただし、?:より右側の処理が行われるのは?:より左側がnullの時のみである。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした