effective java 輪読会 項目57-59
TRANSCRIPT
Effective Java 輪読会
2014/02/26
開発部 田中
項目57
例外的状態にだけ例外を使用する
try-catchはいつ使うべきか
• 例外的条件でのみ使われるべきo 通常の制御フローで例外を使うと可読性を下げる
try {
int i = 0;
while(true)
range[i++].climb();
} catch (ArrayIndexOutOfBoundsException e) {
}
for (Mountain m : range) {
m.climb();
}
これに対する我々の答えは、「例外とは予期せぬ事態に備えるためのものであり、プログラムの通常の流れの一部には組み込むべきではない」というものです。例外がプログラム中で捕捉されなかった場合、そのプログラムは停止します。このような前提を置いた上で、「すべての例外ハンドラーを除去しても、このプログラムは動作することができるだろうか?」と自問してください。答えが「ノー」であれば、例外ではない状況下で例外が使われているはずです。達人プログラマー 24 いつ例外を使用するか
API設計も意識する
• IteratorにhasNextメソッドがない場合..
o 要素がなくなったことをcatchしなければならない
状態検査メソッドが必要
try {
Iterator<Foo> i = collection.iterator();
while(true) {
Foo foo = i.next();
}
} catch (NoSuchElementException e) {
}
状態検査メソッド | 区別できる戻り値
• 使い分けの目安a. 同期なし並行アクセスされるか、外部要因で状態遷移する場合:状態遷移メソッド
b. 状態に依存したメソッドの処理を重複して行う必要がある場合:区別できる戻り値(かも)
項目58
回復可能な状態にはチェックされる例外を、
プログラミングエラーには実行時例外を使用する
Javaの例外
• Javaの例外3種類a. チェック例外
b. 実行時例外
c. エラー
• Throwableo Error
o Exception
RuntimeException
チェック例外 | 実行時例外
• 呼び出し側で適切に処理(回復)可能ならチェック例外を使用するべき
• 事前条件違反(クライアント側の債務不履行)になる場合、実行時例外がスローされるべき
• ErrorはJVMに予約されている慣例があるo 実装しない
• それ以外の独自例外はAPIを複雑にするだけ
項目59
チェックされる例外を不必要に使用するのを避ける
チェック例外が本当に必要か考慮する
• チェック例外は、例外を更にスローするか、クライアントコードで捌くことを強制する。o 開放-閉鎖原則に違反
o クライアントコードが複雑になりがち
o チェック例外を避ける方法がないかを考える
try-catch → if-else
try-catch → if-else
try {
FileInputtream fin = new FileInputStream(“hoge.txt”);
...
} catch (FileNotFoundException e) {
...
}
FileInputStream2 fin = new FileInputStream2(“hoge.txt”);
if (fin.tryOpen()) {
...
} else {
...
}
チェック例外の必要性
契約による設計
• 「あるルーチンにおけるすべての事前条件が呼び出し側によって満足された場合、そのルーチンは作業完了時にすべての事後条件と全ての不変表明を保証する。」
• 「失敗とは、ルーチンの実行で、契約を満足させられなくなること」
つまり
「例外は呼び出す側が契約条件を満たしたが、呼び出された側が契約を履行できなかった時に投げるもの」
開放-閉鎖原則に違反する可能性
まず、検査例外は発生したその場、もしくは直接の呼出し元で処理しない限り、throws に記述せざるを得ない。そうしない場合、より上位層の throws を追加する必要が出てくる。このような追加、もしくは変更は、中間のクラスの再リリースという手間も必要となる。これは、明らかに開放-閉鎖原則に違反する。
開放-閉鎖原則
モジュールは、「拡張」に対して開いており、「修正」に対して閉じていなければならない。
モジュールは、変更容易性がどの部分にあるのかを考慮して、設計されなければならない。
それにより、仕様変更時に「修正」による変更(デグレ)を行わずに、「拡張」による安全な変更を行うことができる、ということ。
DataSpider では..
まとまらない結論
• チェック例外は、開放-閉鎖原則に違反する使い方もできるが、即チェック例外を使用すべきとは判断できない。