Javaの例外とは
Javaの例外(exception)は、プログラムの誤りを通知し、適切なエラー処理を行うための仕組みです。
例えば、次のような状況で例外が発生します。
- 配列の長さを越えた添字で要素を参照しようとした
- ArrayIndexOutOfBoundsException
- ファイルをオープンしようとしたが、ファイルが見つからなかった
- FileNotFoundException
- メソッドに与えられた引数が異常な数値になった
- IllegalArgumentException
- オブジェクトをたくさん作りすぎてメモリが足りなくなった
- OutOfMemoryError
Javaの例外をキャッチ
例外が起きたことを「例外が投げられた」、「例外がthrowされた」といいます。また、例外の処理を行うことを「例外を受ける」、「例外をcatchする」といいます。
それでは、ArrayIndexOutOfBoundsExceptionのエラー処理を書いてみましょう。
public class ExceptionTest{
public static void main(String[] args){
int[] myarray = new int[3];
try{
System.out.println("代入します");
myarray[100] = 0;
System.out.println("代入しました");
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("代入できませんでした")
System.out.println("例外は" + e + "です");
}
System.out.println("終了します");
}
}
上記のプログラムの実行結果は以下になります。
代入します
代入できませんでした
例外はjava.lang.ArrayIndexOutOfBoundsException: 100です
終了します
プログラムの途中に記述してある、「代入しました」と表示するところは、例外が発生したため、出力されませんでした。
つまり、「代入しました」の直前で例外が発生してることがわかります。
このプログラムで例外が発生しているのは、以下の1行です。
myarray[100] = 0;
上記の1行で、配列myarrayのインデックス100に0を代入しようとしています。しかし、下記のようにこの配列myarrayの要素数は3として宣言しています。
int[] myarray = new int[3];
つまり、あるはずのない配列の要素に代入をしようとしているので、例外が発生するということになります。ちなみに、配列myarrayの要素数は3として宣言しているので、インデックスは0,1,2の3つまでとなっていますので、インデックスは最大でも2までしかないということになります。そのため、インデックス100という要素の場所に代入しようとしても例外が発生してしまうということです。
Javaで数へ変換するときの例外
Javaでは”123″のような文字列を整数値に変換することができます。その方法は、IntegerクラスのparseIntメソッドを使います。
int val = Integer.parseInt("123");
parseIntメソッドは文字列が整数値に変換できないときに、NumberFormatExceptionという例外を投げます。
実際に例外の起こるプログラムは下記になります。
public class NumberTest{
public static void main(String() args){
try{
String numstr = "XYZ";
Int val = Integer.parseInt(numstr);
System.out.println("val = " + val);
}catch (NumberFormatException e){
System.out.println("例外:" + e );
}
}
}
通常、”123″というような、文字列の数字であれば、数値に変換することができますが、このプログラムでは、”XYZ”という文字列そのものを数値に変換しようとしています。そのため例外が発生します。
例外が発生しているのは、プログラムの下記の部分です。
String numstr = "XYZ";
Int val = Integer.parseInt(numstr);
String型のnumstrという変数に”XYZ”という文字列を代入し、Integer.parseInt(numstr)で数値に変換して、Int型の変数valに代入しようとしています。しかし”XYZ”という文字列は、数値に変換できませんので、例外が発生することになります。
プログラムの実行結果は下記です。
例外:java.lang.NumberFormatException: For input string: "XYZ"
Javaでファイルを読み込む時の例外
ファイルを読み込む時には、FileReaderクラスを使います。ファイルをオープンするときに、もしもファイルが存在しなかったら(例えば指定したファイル名が間違っている等です)、FileReaderのコンストラクタはFileNotFoundExceptionを投げます。また、ファイルを読んだり、ファイルをクローズするときにエラーが起きたら、例外としてIOExceptionが投げられます。
引数で与えられたファイルを順番にオープンして、そのファイルの内容を画面に表示するプログラムの例外処理は下記になります。
import java.io.*;
public class DisplayFile{
public static void main(String[] args){
for (int i = 0; i < args.length; i++){
System.out.println("ファイル名" + args[i] + "====");
try{
BufferedReader reader = new BufferedReader(new FileReader(args[i]));
while (true){
String line = reader.readLine();
if (line == null){
break;
}
System.out.println(line);
}
reader.close();
}catch (FileNotFoundException e){
System.out.println("ファイルが見つかりません:" + e);
}catch (IOException e){
System.out.println("I/Oエラーです:" + e);
}
}
}
}
上記のプログラム実行時に、引数にnotfileを設定して実行すると、ファイルが見つからずにエラーが発生します。実行結果は下記になります。
ファイル名 nofile====
ファイルが見つかりません: java.io.FileNotFoundException: nofile
Javaのネットワーク処理における例外
インターネットのURLの内容を表示するプログラムで、URLの形式が間違っているときにURLのコンストラクタが投げる例外(MalformedURLException)をキャッチします。
import java.io.*;
import java.net.*:
public class DisplayURL{
public static void main(String[] args){
for (int i = 0: i < args.length; i++){
System.out.println("URL = " + args[i]);
try{
URL url = new URL(args[i]);
BufferReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
while(true){
String line = reader.readLine();
if(line == null){
break;
}
System.out.println(line);
}
reader.close();
}catch(MalformedURLException e) {
System.out.println("URLの形式が誤っています:" + e);
}catch(IOException e) {
System.out.println("I/Oエラーです" + e);
}
}
}
}
上記のプログラムを実行する時の引数に、あえて間違ったURLを引数として設定して実行するとエラーが発生します。
引数として、「abcdef」を設定して実行すると下記の結果になります。
URL = abcdef
URLの形式が誤っています: java.net.MalformedURLException: no protocol: abcdef