Kotlinのtry-catchについて

採用はこちら

Kotlinの try-catch は、プログラム実行中に発生する例外(Exception)を安全に処理するための構文です。

基本的な仕組みはJavaと似ていますが、Kotlinには次のような特徴があります。

  • try式(expression)として扱われる
  • Checked Exception(強制的に処理する例外)がない
  • runCatching など 関数型スタイルの例外処理が存在する

ここでは、基本構文から実務での使い方まで順番に解説します。

目次

try-catchの基本構文

Kotlinの例外処理は次の構造で書きます。

try {
    // 例外が発生する可能性のある処理
} catch (e: ExceptionType) {
    // 例外発生時の処理
} finally {
    // 必ず実行される処理(省略可能)
}

重要なポイントとして、Kotlinでは try を単独では書けません。

必ず catch または finally のどちらかが必要になります。

基本的な使用例

文字列を数値に変換する処理を例にします。

fun main() {
    try {
        val number = "abc".toInt()
        println(number)
    } catch (e: NumberFormatException) {
        println("数値に変換できません")
    }
}

このコードでは "abc" を整数に変換しようとするため、NumberFormatException が発生します。

catch ブロックがその例外を受け取り、エラー時の処理を実行します。

複数のcatchを書く方法

例外の種類ごとに処理を変えることも可能です。

try {
    val numbers = listOf(1, 2, 3)
    println(numbers[5])
} catch (e: IndexOutOfBoundsException) {
    println("配列の範囲外です")
} catch (e: Exception) {
    println("その他のエラー")
}

ここで重要なのは catchの順序です。

  • 具体的な例外を先に書く
  • 抽象的な例外を後に書く

例えば Exception を最初に書くと、後続の catch は実行されなくなります。

finallyブロック

finally は、例外の有無に関係なく必ず実行される処理を書く場所です。

主な用途は次の通りです。

  • ファイルを閉じる
  • データベース接続を解放する
  • ネットワーク接続を終了する

try {
    println("処理開始")
} catch (e: Exception) {
    println("エラー発生")
} finally {
    println("後処理")
}

finally成功・失敗に関係なく実行される点が特徴です。

ただし重要な仕様として、

  • try 式の結果は try または catch の評価結果で決まる
  • finally はその値を決めない

というルールがあります。

Kotlinではtryが「式」

Javaとの大きな違いの一つがこれです。

Kotlinでは try-catch値を返す式として使えます。

val result = try {
    "123".toInt()
} catch (e: NumberFormatException) {
    0
}

println(result)

この場合

  • 変換成功 → 123
  • 例外発生 → 0

result に代入されます。

この特徴は if 式と似ています。

val value = if (condition) A else B

と同じような感覚で使えます。

KotlinにはChecked Exceptionがない

Javaには Checked Exception という仕組みがあります。

  • IOException
  • SQLException

これらは

  • try-catch で処理する
  • throws 宣言を書く

のどちらかが必須でした。

しかしKotlinにはこの強制ルールがありません。

そのため次のようなコードも普通にコンパイルできます。

File("test.txt").readText()

もちろん、必要なら try-catch を書いて例外処理を行います。

catchで複数例外をまとめることはできない

Javaでは次のような書き方があります。

catch (IOException | SQLException e)

しかしKotlinではこの書き方はできません。

代わりに個別の catch を書きます。

catch (e: IOException) {
}

catch (e: SQLException) {
}

throwで例外を投げる

自分で例外を発生させることもできます。

fun checkAge(age: Int) {
    if (age < 0) {
        throw IllegalArgumentException("年齢が不正です")
    }
}

Kotlinでは入力チェックのために次の関数もよく使われます。

  • require
  • check
  • requireNotNull

require(age >= 0) { "年齢が不正です" }

runCatchingによる例外処理

Kotlinには runCatching という関数もあります。

これは処理結果を Result 型で扱うための関数です。

val result = runCatching {
    "123".toInt()
}

結果は次のように取得できます。

result.getOrNull()
result.getOrDefault(0)
result.getOrElse { 0 }

ただし注意点があります。

runCatchingThrowable を捕捉するため、

  • Exception
  • Error
  • CancellationException

なども含めて捕まえます。

そのため、特に コルーチン環境では安易に使わない方が良いケースもあります。

try-catchを使うべき場面

一般的に try-catch外部要因で失敗する処理に使われます。

主な例

  • ファイル読み込み
  • ネットワーク通信
  • JSONパース
  • データベース処理
  • API通信

try {
    val text = File("data.txt").readText()
} catch (e: FileNotFoundException) {
    println("ファイルが見つかりません")
}

try-catchを使わない方がよいケース

例外処理を 通常の条件分岐の代わりに使うべきではありません。

例えば次のコードは望ましくありません。

try {
    val name = user.name!!
} catch (e: NullPointerException) {
}

Kotlinでは次のようなnull安全構文を使います。

user?.name

または

requireNotNull(user)

例外は 異常状態を扱うための仕組みであり、通常の分岐処理として使うべきではありません。

Kotlinの例外処理まとめ

Kotlinの try-catch には次の特徴があります。

  • 例外を安全に処理するための構文
  • try は式として値を返せる
  • Checked Exception が存在しない
  • finally は必ず実行される
  • runCatching による Resultベースの処理も可能

以上、Kotlinのtry-catchについてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次