KotlinのNull安全機能と例外処理を理解してクラッシュを防ぐ【Kotlin入門⑧】

Null安全とは?

Kotlinの最大の特徴の一つが、**Null安全(Null Safety)**です。これは、Nullによるエラー(NullPointerException, NPE)を未然に防ぐための仕組みです。Javaでは、NullPointerExceptionが発生しやすいですが、Kotlinではそれを避ける仕組みが組み込まれています。

Nullable型とNon-Nullable型

Kotlinでは、型に?をつけることで、その変数がnullを許容するかどうかを指定できます。

var nullableString: String? = null // Nullable型
var nonNullableString: String = "Hello" // Non-Nullable型

Non-Nullable型の変数にはnullを代入できません。

nonNullableString = null // コンパイルエラー

Null安全を確保する方法

安全呼び出し(Safe Call Operator)

?. を使うことで、nullの場合にメソッド呼び出しやプロパティアクセスを回避できます。

val length: Int? = nullableString?.length

もし nullableStringnull であれば lengthnull になります。

Elvis演算子(?:)

Elvis演算子(?:)を使うことで、nullだった場合のデフォルト値を指定できます。

val length = nullableString?.length ?: 0

この場合、nullableStringnull なら length には 0 が代入されます。

強制アンラップ(!!)

!! を使うと、変数がnullでないことを保証できます。ただし、実行時にnullの場合はNullPointerExceptionが発生します。

val length = nullableString!!.length // nullableString が null ならクラッシュする

例外処理(Exception Handling)

try-catch文

例外が発生する可能性がある処理には、try-catch を使って適切に対応できます。

try {
    val result = 10 / 0 // 例外発生
    println(result)
} catch (e: ArithmeticException) {
    println("例外発生: ${e.message}")
}

finallyブロック

finally ブロックを使うと、例外が発生しても必ず実行される処理を記述できます。

try {
    println("処理開始")
    val result = 10 / 2
    println(result)
} catch (e: Exception) {
    println("例外発生: ${e.message}")
} finally {
    println("処理終了")
}

throwを使った例外の送出

throw を使って例外を明示的に送出できます。

fun validateAge(age: Int) {
    if (age < 18) {
        throw IllegalArgumentException("年齢は18歳以上でなければなりません")
    }
}

fun main() {
    try {
        validateAge(16)
    } catch (e: IllegalArgumentException) {
        println("エラー: ${e.message}")
    }
}

独自の例外クラスを作成する

Kotlinでは、カスタム例外クラスを作成できます。

class CustomException(message: String) : Exception(message)

fun riskyFunction() {
    throw CustomException("これはカスタム例外です")
}

fun main() {
    try {
        riskyFunction()
    } catch (e: CustomException) {
        println("カスタム例外キャッチ: ${e.message}")
    }
}

Null安全と例外処理の組み合わせ

例外処理とNull安全を組み合わせることで、より安全なコードを書くことができます。

fun safeDivision(a: Int, b: Int?): Int {
    return try {
        a / (b ?: throw IllegalArgumentException("除数はnullではいけません"))
    } catch (e: ArithmeticException) {
        println("エラー: ${e.message}")
        0
    }
}

fun main() {
    println(safeDivision(10, 2))  // 出力: 5
    println(safeDivision(10, null))  // 出力: エラー: 除数はnullではいけません
}

まとめ

本記事では、KotlinのNull安全機能と例外処理について詳しく解説しました。

  • Null安全機能 により、NullPointerException を未然に防ぐことができる。
  • 安全呼び出し (?.)、Elvis演算子 (?:)、強制アンラップ (!!) などを適切に使い分ける。
  • 例外処理 (try-catchfinallythrow) を活用し、コードの安全性を高める。

これらの知識を活かして、安全でクラッシュしにくいKotlinプログラムを構築しましょう!