Kotlinの例外クラスの基本!ExceptionとRuntimeExceptionの違い
生徒
「KotlinでExceptionとかRuntimeExceptionって見かけるんですけど、どう違うんですか?」
先生
「それは例外処理のクラスの種類ですね。エラーの性質や発生タイミングによって使い分けられます。」
生徒
「具体的にどんな場面で違いが出るんですか?」
先生
「では、KotlinにおけるExceptionとRuntimeExceptionの基本を例付きで解説していきましょう。」
1. Kotlinにおける例外クラスとは?エラー処理の全体像
プログラミングをしていると、入力ミスやネットワークの切断など、予期せぬトラブル(エラー)がどうしても発生します。Kotlinでは、これらの問題を「例外(Exception)」という仕組みを使って管理します。
Kotlinのすべての例外は、Throwableという大元のクラスを継承しています。この下には、主に2つの重要なクラスがあります。
- Error(エラー): メモリ不足など、プログラム側ではどうしようもない致命的な問題。
- Exception(例外): プログラムの書き方や処理の工夫で、適切に対処・回復ができる問題。
今回詳しく学ぶのは、後者の「Exception」です。まずは、最もシンプルな例外が発生するイメージを、プログラミングが初めての方でも分かりやすいコードで見てみましょう。
fun main() {
// 例えば、数字ではない文字を無理やり数字に変換しようとすると...
val text = "こんにちは"
// ここで「そんなの無理だよ!」という例外が発生します
val number = text.toInt()
println("この行は実行されません: $number")
}
このコードを実行すると、プログラムは途中で止まり「NumberFormatException」という例外が表示されます。このように、例外クラスは「何が原因で処理が止まったのか」を名前で教えてくれる役割を持っています。
その中でも、開発者が特によく扱うのが、基本的なExceptionクラスと、その一種であるRuntimeExceptionです。これらがどのように使い分けられるのか、次の章から詳しく解説していきます。
2. Exceptionクラスとは?(例外処理の基本)
プログラミングをしていると、ファイルが見つからない、ネットワークが途切れるといった「予期せぬトラブル」が発生することがあります。KotlinのExceptionクラスは、こうしたエラーをキャッチし、プログラムが強制終了するのを防ぐために使われます。
本来、Javaなどでは「チェック例外」として厳密に区別されますが、Kotlinではより柔軟に扱えるのが特徴です。まずは「何か問題が起きた時に投げるバトン」のようなものだと考えてみましょう。未経験の方でも分かりやすいよう、条件に合わない場合にエラーを発生させるシンプルな例を紹介します。
// ユーザーの年齢をチェックする関数
fun checkAge(age: Int) {
if (age < 0) {
// Exception(例外)を発生させて、後続の処理をストップさせる
throw Exception("年齢にマイナスの値は入力できません")
}
println("登録を受け付けました:$age 歳")
}
fun main() {
try {
// 0未満の値を渡して、わざとエラーを発生させてみる
checkAge(-5)
} catch (e: Exception) {
// エラーが発生した場合、ここが実行される
println("【システム通知】${e.message}")
} finally {
println("処理が完了しました")
}
}
【システム通知】年齢にマイナスの値は入力できません
処理が完了しました
このコードでは、年齢がマイナスという「本来ありえない状況」に対し、Exceptionを使って安全にエラーを通知しています。try-catch構文と組み合わせることで、アプリが突然落ちるのを防ぎ、ユーザーに適切なメッセージを表示できるようになります。このように、事前に予測できるエラーを管理するのがExceptionの役割です。
3. RuntimeException(実行時例外)とは?初心者向けにわかりやすく解説
RuntimeExceptionは、日本語で「実行時例外(unchecked exception)」と呼ばれます。これは、アプリの作成中(コンパイル時)にはエラーになりませんが、実際にプログラムを動かしている最中に、予想外の事態が起きて発生するエラーのことです。
例えば「数字を0で割ろうとした」「存在しないデータにアクセスしようとした」など、論理的なミスが原因で起こることが多く、プログラミング未経験の方でも直面しやすいエラーの代表格です。JavaやKotlinでは、この例外を適切に処理することで、アプリが突然強制終了してしまうのを防ぐことができます。
以下のサンプルコードは、計算機アプリなどで「0で割り算」をしてしまった際のエラーをキャッチする例です。初心者の方でも理解しやすいよう、具体的な条件分岐とエラーメッセージを用いて解説します。
fun divide(a: Int, b: Int): Int {
// 0で割るという不正な操作をチェックする
if (b == 0) {
// RuntimeExceptionを発生させて、異常を知らせる
throw RuntimeException("0で割ることはできません")
}
return a / b
}
fun main() {
// try-catch構文を使って、エラーが起きてもアプリを止めないようにする
val result = try {
// ここでわざと0を渡してエラーを発生させる
divide(10, 0)
} catch (e: RuntimeException) {
// エラーが発生した時の処理
println("実行時エラーをキャッチしました: ${e.message}")
-1 // エラー時の代わりの値
}
println("計算結果: $result")
println("プログラムは無事に終了しました。")
}
実行時エラーをキャッチしました: 0で割ることはできません
計算結果: -1
プログラムは無事に終了しました。
このコードのポイントは、エラーが発生してもcatchブロックがその衝撃を吸収してくれる点です。もしtry-catchを使わずにdivide(10, 0)を実行すると、アプリはエラーメッセージを出してその場で止まってしまいます。RuntimeExceptionを正しく理解することは、ユーザーに不快感を与えない「止まらないアプリ」を作るための第一歩です。
4. ExceptionとRuntimeExceptionの使い分け
プログラムを動かしていると、どうしても避けられない「エラー(例外)」が発生します。 KotlinやJavaの世界では、これらを大きく「Exception(チェックされる例外)」と「RuntimeException(実行時例外)」の2種類に分けて管理します。 初心者の方でも分かりやすいように、具体的なシチュエーションで解説します。
① Exception:事前に予測できる「外的な要因」
「ファイルが開けない」「ネットワークがつながらない」といった、プログラム自体にミスがなくても、環境によって起こり得るエラーです。 あらかじめ「もしダメだったらこうする」という準備(例外処理)をしておくべきケースです。
② RuntimeException:防ぐことができる「内的なミス」
「数値の0で割り算をした」「中身が空っぽ(null)の変数にアクセスした」など、主にプログラミングのロジックミスで発生します。 これらは事前にチェック処理(if文など)を書くことで、本来は回避できるはずのエラーです。