例外処理について
例外処理とは、いわゆるエラー処理のことです(厳密にいうと違うようですが)。
エラーの例
- ゼロで除算してしまった
- 配列のサイズを超えるデータを受け付けた
- 存在しないファイルを開いた
など。。。さまざまです。
良いプログラムとは=エラーに対応して異常終了を回避できるプログラム。
大学(授業で)で作るプログラムと企業が作るプログラムの違い=エラー処理に対する認識の違い(エラーにしっかり対応するかどうか?)
エラーを回避するには?
プログラマーがエラーを回避するようなアルゴリズムを考える
しかしこれには、限界があります(プログラマー個人の能力に依存する危険性を持つ)。プログラマーがエラーを予測できない恐れがある。
Javaの例外処理
Javaは言語仕様として例外処理という枠組みを持っています。主にエラー処理を目的に使われます。例外処理の書き方は以下のとおりです。
try ~catch構文
try{
例外が発生する可能性のある処理
}catch(例外の種類の引数){
例外が発生した場合の処理
}
(解説)
- tryブロックでエラーが発生したら、catchブロックでエラーをキャッチする
- 例外の種類は複数存在する
例外の種類とは
プ ログラムを離れて、球技をイメージしてください。野球、サッカー、ソフトボール、ハンドボール.....ボールが違えばそれを受取るミットも種類が変わっ てきますね。これと同じで、エラーにも様々な種類がありますので、それに応じたミットで拾う必要があります。では、どんな例外の種類があるか?それは利用 するクラスが定義しています。とりあえず、以下のサンプルを入力してみましょう。
簡単にいうと、下記のプログラムはtest.txtというファイルを開いて "aaaaa"という文字列を追記しようとしています。
sample3_1.java
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.PrintWriter;
public class sample3_1 {
public static void main(String[] args) {
String filename = "\test.txt";
//追記モードでファイルをオープン
PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(filename,true)));
writer.println("aaaaa") ;
writer.close();
}
}
入力ができたら、コンパイルをしてみましょう。すると以下のようなメッセージが出るはずです(少し表現が違うかもしれません)。
sample3_1.java:34: 例外 java.io.IOException は報告されません。スローするにはキャッチまたは、スロー宣言をしなければなりません。
PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(filename,true)));
エラー 1 個
なんかわけもわからない日本語がでてますが、それはご愛敬。このメッセージが言わんとすることは
「java.io.IOExceptionという例外が起きる可能性があるんだが、キャッチしてないぞ!」
ということです。
そこで、以下のように修正を行います。
sample3_1.java 改良版
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class sample3_1 {
public static void main(String[] args) {
String filename = "\test.txt";
PrintWriter writer;
try {
writer = new PrintWriter(new BufferedWriter(new FileWriter(filename, true)));
writer.println("aaaaa") ;
writer.close();
} catch (IOException ex) {
System.out.println("IOExceptionが発生しました");
}
}
}
#このサンプルでは、例外が発生したというメッセージを出してますが、本来は適切な処理をするべきです。
こ こで理解してほしいのは、「ファイルオープンをする処理をする際には、IOException、つまりファイルがないというエラーが発生することがある」 ということを通知し、エラー処理をするようにコンパイル時に気づかせてくれているということです。これは、FileWriterというクラスを作成した人 がそのようにクラスを作成しているというおかげなのですが、Javaはそういった枠組みを言語として持っています。
ただし、自動的にエラーの可能性を分析してくれているというわけではないので注意してください。以下のソースをコンパイルしてみて下さい。
sample3_2.java
public class sample3_2 {
public static void main(String[] args) {
int a =5;
int b= 0;
System.out.println(a/b);
}
}
この場合、コンパイルエラーは発生しません。しかし、実行をするといかのようなエラーが発生します。
実行エラー
Exception in thread "main" java.lang.ArithmeticException: / by zero
at kochi.example3.sample3_2.main(sample3_2.java:20)
こ れは、「java.lang.ArithmeticException」という例外が発生し異常終了しているいう意味です。sample3_2.java を見ればわかるように、ゼロで除算をしようとしているので、例外が発生したわけです。ただ、Javaはこのエラーを 「java.lang.ArithmeticException」という例外として認識しているようです。つまり、このエラーであれば try~ catchを利用することで、プログラム中で解決できるということになります。
つまり、いかのようなソースコードを書くことがベターとなります。
sample3_3.java
package kochi.example3;
public class sample3_3 {
public static void main(String[] args) {
int a =5;
int b= 0;
try {
System.out.println(a/b);
} catch (java.lang.ArithmeticException e) {
System.out.println("0の除算が発生しました");
}
}
}
これで、異常終了ではなく、プログラムの範囲内で処理が終わります。もちろん、上記の例外処理の内容は仮であり適切な処理をする必要はあります。