こんなに例外がやっかいだったとは・・・。
ふたつのファイルからデータを読んで、ひとつのファイルに書き込むプログラムを書いてみました。
File in1 = new File("in1.txt");
File in2 = new File("in2.txt");
File out = new File("out.txt");
BufferedReader br1 = null;
BufferedReader br2 = null;
PrintWriter pw = null;
try{
br1 = new BufferedReader(new FileReader(in1));
br2 = new BufferedReader(new FileReader(in2));
pw = new PrintWriter(new FileWriter(out));
// てけとーに処理
// ...
}catch(FileNotFoundException e){
throw new RuntimeException(e);
}catch(IOException e){
throw new RuntimeException(e);
}finally{
try{
if(br1 != null) br1.close();
if(br2 != null) br2.close();
if(pw != null) pw.close();
}catch(IOException e){
throw new RuntimeException(e);
}
}
IBMのページの"必ずしも見た目ほど容易ではない"で書かれてるように、BufferedReader#close()がExceptionで落ちて以下のclose()が呼ばれない可能性があります、と。*1 そこでfinallyの中を変えます。
... 前略 ...
}finally{
try{
try{
if(br1 != null) br1.close();
}finally{
try{
if(br2 != null) br2.close();
}finally{
if(pw != null) pw.close();
}
}
}catch(IOException e){
throw new RuntimeException(e);
}
}
tryがたくさん出てきて意欲満々な感じのソースですが、あまり好きくありません。ので、以下のように書いてみました。
... 前略 ...
}finally{
Exception occured = null;
try{ if(br1 != null) br1.close(); }
catch(IOException e){ occured = e; }
try{ if(br2 != null) br2.close(); }
catch(IOException e){ occured = e; }
if(pw != null) pw.close();
if(pw.checkError()) occured = new IOException();
if(occured != null)
throw new RuntimeException(occured);
}
こんな感じになりました*2。ネストするよりはマシだと思いますが、どうでしょう?