
Javaの例外処理で知らないと損する7つのテクニック
株式会社ガリレオ
小山博史
2011/12/20
これからプログラミングを学習したい方、Javaは難しそうでとっつきづらいという方のためのJavaプログラミング超入門連載です。最新のEclipseとJava 6を使い大幅に情報量を増やした、連載「Eclipseではじめるプログラミング」の改訂版となります(この回と前回のみ、別連載「EclipseでJavaに強くなる」の改訂版です。今回は第4回Javaの例外のテクニックを知る」の改訂版です)
| 今回の主な内容 ・【1】Eclipseで独自の例外クラスを定義するには ・【2】「throw」「throws」で例外を「投げる」には ・【3】独自の例外に置き換えてthrowするには ・【4】finallyでリソースの解放を確実に行うには ・【5】読み書きでfinallyを使う際の注意点 ・【6】コンパイル時にチェックされる例外 を使いたくない場合 ・【7】例外処理を有効に使うための心構え |
前回の「プログラマの宿命! 例外とエラー処理を理解する」では、Javaにおける例外の用途と基本的なコードの書き方、例外が発生するさまざまなケースについて理解しました。
今回は、独自に例外を定義する方法や、ちょっとした例外のテクニックを紹介します。
【1】Eclipseで独自の例外クラスを定義するには
独自の例外を定義する場合の基本は、java.lang.Exceptionを継承する例外クラスを定義することです。ここではsample24.SampleExceptionというクラスを作成してみましょう。Eclipseで例外クラスを定義するには下記のような手順になります。あらかじめsample24パッケージを作成しておいてください。
- [ファイル]→[新規作成]→[クラス]で[新規Javaクラス]ダイアログを表示
- パッケージへ「sample24」、クラス名へ「SampleException」を入力
- [スーパークラス]の[参照]で[スーパークラスの選択]ダイアログを表示
- 「Exception」と入力し[OK]ボタンをクリック
- mainメソッドを生成していない設定になっていることを確認して[終了]
![]() |
| 画面1 [新規Javaクラス]ダイアログ |
SampleExceptionクラスを作成したら、次のようにコーディングを完成させてください。
package sample24;
public class SampleException extends Exception {
private static final long serialVersionUID = 1L;
private int code;
public SampleException(int code, String message) {
super(message);
this.code = code;
}
public int getCode() {
return code;
}
}ここでは、サンプルなのでcodeフィールドを用意しました。こういったフィールドを用意しておけば、独自のエラーコードを設定して、問題の切り分けがしやすいエラーメッセージを出力できます。
■ 「serialVersionUID」フィールドとは
なお、「serialVersionUID」というフィールドについては、Exceptionクラスをextendsしたクラスはシリアライズ可能なクラスとして、このフィールドを持つようにするのがいいため、用意しています。ここでは、こう書いておけばEclipseで警告が出ないと覚えておけばいいでしょう。
■ 特別なフィールドを持たない例外クラスを定義するには
どんな例外が発生したかを例外クラスの型だけで表現することも多いので、特別なフィールドを持たない例外クラスを定義することもあるでしょう。そういった場合は、次のSampleException2のようなクラスを定義すれば十分です。
package sample24;
public class SampleException2 extends Exception {
private static final long serialVersionUID = 1L;
public SampleException2(String message) {
super(message);
}
}
【2】「throw」「throws」で例外を「投げる」には
次に、この例外を「投げる」メソッドを持つクラスを作成します。メソッドでは、どんな例外を投げるか宣言する必要があるので、キーワード「throws」を使って投げる例外クラスを記述します。
■ 例外を投げるサンプルクラス
ここでは、名前とパスワードというユーザー情報をUserInfoクラスで表現し、ユーザー情報のリストをフィールドusersで持つSampleUserListクラスを用意します。
このクラスのメソッドとして、nameとpasswordをパラメータとするloginメソッドを作成しますが、例外が発生した場合にはSampleExceptionとSampleException2を投げるようにthrowsをメソッドへ付けます。
package sample24;
public class SampleUserList {
class UserInfo {
private String name;
private String password;
public UserInfo(String name, String password) {
this.name = name;
this.password = password;
}
public String getName() { return name; }
public String getPassword() { return password; }
}
private java.util.List users =
new java.util.ArrayList();
public SampleUserList() {
users.add(new UserInfo("Akira", "777"));
users.add(new UserInfo("Jacky", "*"));
}
public boolean login(String name, String password)
throws SampleException, SampleException2 {
for (UserInfo user : users) {
if ("".equals(name.trim())) {
throw new SampleException(1, "ログインに失敗しました。");
} else if ("".equals(password.trim())) {
throw new SampleException(2, "ログインに失敗しました。");
}
if (user.getName().equals(name)) {
if (user.getPassword().equals("*")) {
throw new SampleException2("ログインに失敗しました。");
} else if (user.getPassword().equals(password)) {
return true;
} else {
return false;
}
}
}
return false;
}
} メソッドの中では例外を投げる条件が満たされているときに、キーワード「throw」を使って例外を投げます。普通は例外のインスタンスを新規に生成して投げます。
ここでは、SampleExceptionの例外を投げる条件は、nameの先頭と最後の空白を省略した結果が空文字列である場合か、passwordの先頭と最後の空白を省略した結果が空文字列の場合としました。このとき、どちらが原因となって例外が発生したのか分かるようにSampleExceptionのcode値を変えています。
また、nameに対応するpasswordに「*」という文字列が設定されている場合は、そのnameが無効になっていると想定して、SampleException2の例外を投げるようにしています。
■ 例外を受け取るサンプルクラス
SampleUserAppクラスを使用して動作するプログラムは次のようになります。SampleUserAppクラスのloginメソッドが投げるSampleExceptionとSampleException2をcatchで受け取るようにtry文を記述しています。処理が実行されている順番が分かるように、すべて標準エラー出力へメッセージを出力しています。
package sample24;
public class SampleApp {
public static void main(String[] args) {
String[] users = { "Sara", "Akira", "Akira", "Jacky", "" };
String[] passwords = { "", "777", "111", "abc", "xyz" };
SampleUserList sample = new SampleUserList();
for (int i = 0; i < users.length; i++) {
try {
System.err.print("i=" + i + ":");
boolean isLogin = sample.login(users[i], passwords[i]);
if (isLogin) {
System.err.println("ログインに成功しました。(" + users[i] + ")");
} else {
System.err.println("ログインに失敗しました。");
}
} catch (SampleException e1) {
e1.printStackTrace();
System.err.println("code[" + e1.getCode() + "]");
} catch (SampleException2 e2) {
e2.printStackTrace();
}
System.err.println("");
}
}
}■ 例外を投げるサンプルの実行結果
これを実行すると、画面2のようになります。
![]() |
| 画面2 実行結果 |
nameが「Sara」でpasswordが半角空白の文字列だと、SampleUserAppクラスのloginメソッドはSampleExceptionを投げるので、それをキャッチしたcatch節の処理が実行されます。この結果スタックトレースが出力された後、codeの値である2が出力されています。
次に、nameが「Akira」でpasswordが「777」の場合は正しい情報であるため例外は投げられずに正常に処理が終了しています。
次に、nameが「Akira」でpasswordが「111」の場合は正しいパラメータを渡しているためパスワードが一致しない結果となるだけで例外が発生しません。次のname「Jacky」はパスワードが「*」で無効となっているユーザーであるため、SampleException2の例外が発生します。
最後は、nameが「""」であるため、SampleExceptionの例外が発生しています。このように、意図したとおりに例外が投げられて、それをキャッチして処理が行われていることが分かるはずです。
| Index | ||||||||
|
||||||||
【改訂版】Eclipseではじめるプログラミング バックナンバー 連載インデックスへ»
- 第1回 Eclipse 3.4で超簡単Javaプログラミング基礎入門
- 第2回 Javaで一から理解するプログラムの変数と演算子
- 第3回 プログラミングの醍醐味! Javaで“条件式”を理解する
- 第4回 プログラミングの真骨頂! Javaで“反復処理”を覚える
- 第5回 データ集合を扱うのに便利なJavaの配列と拡張for文
- 第6回 複雑なデータを表現できるクラスやフィールドって?
- 第7回 クラスの振る舞いを表すJavaの“メソッド”とは?
- 第8回 Javaの参照型を文字列操作で理解して文法を総復習
- 第9回 プログラムを「変更」しやすくする“インターフェイス”
- 第10回 Javaの実案件に必須のパッケージとインポートを知る
- 第11回 「static」でクラス共有の変数・メソッドを使いこなせ!
- 第12回 継承やオーバーライドで簡単にクラスを“拡張”しよう
- 第13回 “コンストラクタ”と初期化、本当に理解できてる?
- 第14回 再利用性の高いクラス作成に重要な“アクセス制御”
- 第15回 Javaは「抽象クラス」で実装を上手に再利用できる
- 第16回 “ネスト”した型で始める軽量Javaプログラミング!?
- 第17回 あなたの知らない、4つのマニアックなJava文法
- 第18回 強く型付けされているJavaの理解に必修の“型変換”
- 第19回 キュー構造をJavaで実装してジェネリック型を理解する
- 第20回 拡張for文の真の実力を知り、反復処理を使いこなせ
- 第21回 7ステップで理解するJavaでの列挙型/enum使用法
- 第22回 いまさら聞けない「Javadoc」と「アノテーション」入門
- 第23回 プログラマの宿命! 例外とエラー処理を理解する
- 第24回 Javaの例外処理で知らないと損する7つのテクニック
| Java Solution全記事一覧 |
TechTargetジャパン
- Scalaのパッケージ、アクセス修飾子、オブジェクト継承 (2012/5/22)
インポート、パッケージオブジェクト、抽象クラス/抽象メソッド、オーバーライド、final、シールドクラスなども - 基幹系システムでCloud SQLは使えるか試してみた (2012/5/17)
サンプルとしてMRPシステムを作成して動かし、「再帰呼び出し」などのパフォーマンスを測定して検証してみます - アジャイル管理ツール9選+Pivotal Tracker入門 (2012/5/14)
群雄割拠のアジャイルプロジェクト管理ツールを9つ紹介し、特に注目を集めているPivotal Trackerの基本的な使い方を解説します - サーバサイドJSやJavaでWebアプリが作れるXPages (2012/5/11)
Notes/Dominoの資産をサーバサイドJavaScriptやJavaで操作し、HTMLやJavaScript、CSSをUIにできる技術を紹介
|
|
キャリアアップ
スポンサーからのお知らせ
- - PR -
イベントカレンダー
- - PR -


