30.
エラーハンドリング
エラーハンドリングとは
エラーハンドリングの意味
プログラム実行中にエラーが発生すると、通常のプログラムは異常終了してしまいます。プログラムを継続的に実行するには、例外処理で回避しなければいけませんが、これをエラーハンドリングといいます。
エラーハンドリングの種類
エラーハンドリング(例外処理) をするとき、以下の3つの構文があります。
- try-catch
- throw
- throws
try-catch
try-catchの基本構文
try-catch文は、tryブロックとcatchブロックで構成されます。
- tryブロックには例外が発生する可能性のある処理
- catchブロックに例外が発生したときの処理
- catch*の引数には例外クラスを指定
try {
//例外発生の可能性がある処理
} catch (例外クラス インスタンス) {
//例外処理が発生したときの処理
}
複数の例外catch
try-catch文は複数のcatchブロックを記述できます。
try {
//例外発生の可能性がある処理
} catch (例外クラス1 インスタンス1) {
// 対策処理1
} catch (例外クラス2 インスタンス2) {
// 対策処理2
} finally {
// 例外に関わらず必ず実行する処理
}
finally
finallyは例外が発生しなくても必ず最後に処理されるブロックです。
try {
//例外発生の可能性がある処理
} catch (例外クラス1 インスタンス1) {
// 対策処理1
} catch (例外クラス2 インスタンス2) {
// 対策処理2
} finally {
// 例外に関わらず必ず実行する処理
}
外部ファイル読み込み
ファイル構成
./
└── data/
└── sample.txt
└── src/
└── sample/
└── FileLoadApp.java
テキストファイルの準備
「data/sample.txt」にテキストを記述しておきます。
sample.txt
Hello
こんにちは
FileInputStream
FileInputStreamは、外部ファイルを開くためのクラスです。
FileInputStream file = new FileInputStream(ファイルパス);
loadFile() メソッドで、指定されたパスからファイルを読み込んでみます。
ExceptionApp.java
public static void loadFile(String path) {
FileInputStream file = new FileInputStream(path);
}
try-catchで例外処理
FileInputStreamインスタンスを作成をすると、コンパイルエラーになります。これはファイルが読み込まれない可能性があるからです。

クイックフィックスでtry-catch文を追加して、FileInputStreamの処理を囲みます。

try-catchを追加したら、通常処理と例外処理を記述しましょう。
FileLoadApp.java
public static void loadFile(String path) {
// try-catch の追加
try {
FileInputStream file = new FileInputStream(path);
System.out.println("ファイルを開きました");
} catch (FileNotFoundException e) {
// FileNotFoundException の追加
System.out.println("ファイルが開けませんでした");
}
}
動作確認
loadFile() にファイルパスを指定して、ファイルが読み込めるか確認してみましょう。
FileLoadApp.java
public static void main(String[] args) {
loadFile("./data/sample.txt");
}
ファイルが存在すれば、ファイルが読み込まれます。
結果
ファイルを開きました
InputStreamReader
InputStreamReaderの基本
InputStreamReaderクラスは、ファイルを読み込むためのクラスです。第2引数には文字エンコードを指定できます。
InputStreamReader reader = new InputStreamReader(リソース, 文字エンコード);
作成したInputStreamReaderで処理が終わったら閉じます。
reader.close();
InputStreamReaderで読み込み準備
FileInputStreamから、InputStreamReaderを作成します。
ExceptionApp.java
public static void loadFile(String path) {
try {
FileInputStream file = new FileInputStream(path);
InputStreamReader reader = new InputStreamReader(file, "UTF-8");
System.out.println("ファイルを開きました");
reader.close();
} catch (FileNotFoundException e) {
System.out.println("ファイルが開けませんでした");
} catch (IOException e) {
System.out.println("データエラー");
}
}
- 例外処理が必要なため、コンパイルエラーとなります。
- Windowsでは第2引数に文字エンコードを指定して読み込みます。
- InputStreamReaderでは、文字エンコードの例外処理が必須です。
BufferedReaderクラス
BufferedReaderの基本
BufferedReaderクラスは、InputStreamReaderからデータを行単位で読み込むことができます。
BufferedReader buffer = new BufferedReader(reader);
作成したBufferedReaderで処理が終わったら閉じます。
buffer.close();
BufferedReaderでデータ読み込み
while文で外部ファイルデータを1行ずつ読み込みます。
FileLoadApp.java
public static void loadFile(String path) {
try {
FileInputStream file = new FileInputStream(path);
InputStreamReader reader = new InputStreamReader(file, "UTF-8");
System.out.println("ファイルを開きました");
BufferedReader buffer = new BufferedReader(reader);
String line;
//1行ずつ繰り返し読み込み
while ((line = buffer.readLine()) != null) {
System.out.println(line);
}
buffer.close();
reader.close();
} catch (FileNotFoundException e) {
System.out.println("ファイルが開けませんでした");
} catch (IOException e) {
System.out.println("データエラー");
}
}
readLine() では例外処理が必須のため、現状ではコンパイルエラーになります。

IOExceptionのcatch
クイックフィックスで、例外を catch します。

IOExceptionクラスの catchブロックが追加されました。
FileLoadApp.java
public static void loadFile(String path) {
try {
FileInputStream file = new FileInputStream(path);
InputStreamReader reader = new FileInputStream(file, "UTF-8");
System.out.println("ファイルを開きました");
BufferedReader buffer = new BufferedReader(reader);
String line;
while ((line = buffer.readLine()) != null) {
System.out.println(line);
}
buffer.close();
reader.close();
} catch (FileNotFoundException e) {
System.out.println("ファイルが開けませんでした");
} catch (IOException e) {
// IOException の追加
System.out.println("ファイルエラー");
}
}
finallyの追加
finallyブロックを追加して、共通処理を記述します。
FileLoadApp.java
public static void loadFile(String path) {
try {
...
} catch (FileNotFoundException e) {
System.out.println("ファイルが開けませんでした");
} catch (IOException e) {
System.out.println("ファイルエラー");
} finally {
System.out.println("ファイル読み込み処理を終了します");
}
}
動作確認
プログラムを実行して「data/sample.txt」ファイルのテキスト内容が表示できるか確認してみましょう。
結果(ファイルがある場合)
ファイルを開きました
Hello
こんにちは
ファイル読み込み処理を終了します。
結果(ファイルがない場合)
ファイルが開けませんでした
ファイル読み込み処理を終了します
throws
throwsとは
throwsは例外が発生したときに、呼び出し元に例外処理を投げる方法です。
public メソッド() throws 例外 {
//例外の可能性のある処理
}
ファイル読み込み(throws)
loadFile2() メソッドで同じようにファイル読み込み処理を作成します。
FileLoadApp.java
public static void loadFile2(String path) {
FileReader reader = new FileReader(path);
System.out.println("ファイルを読み込みました");
BufferedReader buffer = new BufferedReader(reader);
String line;
while ((line = buffer.readLine()) != null) {
System.out.println(line);
}
buffer.close();
reader.close();
}
throwsの追加
readLine() を選択し、クイックフィックスでthrowsを追加します。

メソッドに throws IOExceptionが追加されました。
FileLoadApp.java
public static void loadFile2(String path) throws IOException {
FileReader reader = new FileReader(path);
System.out.println("ファイルを読み込みました");
BufferedReader buffer = new BufferedReader(reader);
String line;
while ((line = buffer.readLine()) != null) {
System.out.println(line);
}
buffer.close();
reader.close();
}
呼び出し元で「try-catch」
コンパイルエラー
loadFile2() を実行するとコンパイルエラーになります。
FileLoadApp.java
public static void main(String[] args) {
...
loadFile2("./data/sample.txt");
}
try-catchの追加
呼び出し元で「try-catch」文を追加します。

try-catch文が作成されたら、通常処理と例外処理を記述しましょう。
FileLoadApp.java
public static void main(String[] args) {
...
try {
loadFile2("./data/sample.txt");
} catch (IOException e) {
System.out.println("ファイルエラー");
}
}
動作確認
プログラムを実行して動作確認してみましょう。
結果
Hello
こんにちは
throw
throwは、意図的に例外を発生させて処理します。例えば値が想定と違う場合、意図的に例外を発生させ、エラーメッセージを返すことができます。
throw new Exceptionクラス(値);
throwの例
countがマイナスの数値と判別したら、IllegalArgumentExceptionを発生させて、catchで処理します。
ExceptionApp.java
public static void main(String[] args) {
int score = 100;
int count = -1;
float average = 0;
average = calculateAverage(score, count);
System.out.println(average);
}
public static float calculateAverage(int score, int count) {
// return score / count;
try {
if (count < 0) {
throw new IllegalArgumentException();
}
} catch (IllegalArgumentException e) {
System.out.println("個数がマイナスです。");
return 0;
}
if (count > 0) {
return (float) score / count;
} else {
System.out.println("個数が間違っています。");
return 0;
}
}
例外が catchできました。
結果
個数がマイナスです。
演習
問題1
「IOException」の例外処理をする「try-catch」文で正しいのはどれですか?
- try { } catch { }
- try (IOException e) { } catch { }
- try { } catch (IOException e) { }
- try (IOException e) { } catch (IOException e) { }
問題2
「IOException」の例外処理をする「throws」文で正しいのはどれですか?
- public check() throws IOException { }
- public check(IOException e) throws { }
- public check() throws IOException(e) { }
- public check(throws IOException) { }
問題3
Nullを強制的に発生させる処理で、正しいのはどれですか?
- NullPointerException();
- throw NullPointerException();
- new NullPointerException();
- throw new NullPointerException();