こんなに例外がやっかいだったとは・・・。
ふたつのファイルからデータを読んで、ひとつのファイルに書き込むプログラムを書いてみました。
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。ネストするよりはマシだと思いますが、どうでしょう?