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では入力チェックのために次の関数もよく使われます。
requirecheckrequireNotNull
例
require(age >= 0) { "年齢が不正です" }
runCatchingによる例外処理
Kotlinには runCatching という関数もあります。
これは処理結果を Result 型で扱うための関数です。
val result = runCatching {
"123".toInt()
}
結果は次のように取得できます。
result.getOrNull()
result.getOrDefault(0)
result.getOrElse { 0 }
ただし注意点があります。
runCatching は Throwable を捕捉するため、
ExceptionErrorCancellationException
なども含めて捕まえます。
そのため、特に コルーチン環境では安易に使わない方が良いケースもあります。
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についてでした。
最後までお読みいただき、ありがとうございました。










