Automatic Resource Managementについて

Java7で導入される新機能"Automatic Resource Management"(自動リソース管理?)について、InfoQに記事が上がっていたので、試してみた。

InfoQ記事: Automatic Resource Management in Java

Automatic Resource Managementって何?

Java7で追加される新構文。詳細については上の記事を見てもらうとして、どのような機能かというと・・・下記のようにファイル入出力等の外部リソースを扱う場合、従来のJavaコードではいちいちReader/Writerを閉じる処理を記述する必要があった。閉じるだけならまだいいけど、オブジェクトのnullチェックとかめんどい。しかも結構出てくるパターンなので、なおさらめんどい。

従来コードの例

BufferedReader inBuffer = null;
BufferedWriter outBuffer = null;
try {
	FileReader inFile = new FileReader("xanadu.txt");
	FileWriter outFile = new FileWriter("outagain.txt");
	inBuffer = new BufferedReader(inFile);
	outBuffer = new BufferedWriter(outFile);
	String line;
	while((line=inBuffer.readLine()) != null ){
		outBuffer.write(line);
	}
} catch (IOException ioe){
	//例外処理 doSomething...
	ioe.printStackTrace();
} finally {

	//BufferedReaderを閉じるよ
	try{
		if(inBuffer != null){
			inBuffer.close();
		}
	} catch(IOException ioe){}

	//BufferedWriterを閉じるよ
	try{
		if(outBuffer != null){
			outBuffer.close();
		}
	} catch(IOException ioe){}
}

で、 Automatic Resource Management構文を使うと、上記のコードは以下のように書ける。

try (
	//try()の中にファイル入出力処理を書く
	FileReader inFile = new FileReader("xanadu.txt");
	FileWriter outFile = new FileWriter("outagain.txt");
	BufferedReader inBuffer = new BufferedReader(inFile);
	// ラスト一行はセミコロン不要
	BufferedWriter outBuffer = new BufferedWriter(outFile)
) {
	String line;
	while((line=inBuffer.readLine()) != null ){
		outBuffer.write(line);
	}
} catch (IOException ioe){
	//例外処理 doSomething...
	ioe.printStackTrace();
}

要は、try後の()で囲まれたブロック内でjava.io.Closeableインターフェイスの実装クラスをnewすると、勝手にclose処理を行ってくれるというのが"Automatic Resource Management"。単にclose処理をするだけなんで、もちろんエラーハンドリングは自前でやる必要がある。

デコンパイルしてみる

実際にどんなコードが生成されているのか確認するため、java7 build-107でコンパイルしてみた上記のコードを、JDを使ってデコンパイルしてみる。結果は以下ような感じ。

    try
    {
      FileReader localFileReader = new FileReader("xanadu.txt");

      Object localObject1 = null;
      try {
        FileWriter localFileWriter = new FileWriter("outagain.txt");

        Object localObject2 = null;
        try
        {
          BufferedReader localBufferedReader = new BufferedReader(localFileReader);

          Object localObject3 = null;
          try
          {
            BufferedWriter localBufferedWriter = new BufferedWriter(localFileWriter);

            Object localObject4 = null;
            try
            {
              while ((str = localBufferedReader.readLine()) != null)
              {
                String str;
                localBufferedWriter.write(str); } } catch (Throwable localThrowable8) {
            } finally {
              if (localObject4 != null) try { localBufferedWriter.close(); } catch (Throwable localThrowable9) { localObject4.addSuppressedException(localThrowable9); } else localBufferedWriter.close();  } } catch (Throwable localThrowable6) { } finally {
            if (localObject3 != null) try { localBufferedReader.close(); } catch (Throwable localThrowable10) { localObject3.addSuppressedException(localThrowable10); } else localBufferedReader.close();  } } catch (Throwable localThrowable4) { } finally {
          if (localObject2 != null) try { localFileWriter.close(); } catch (Throwable localThrowable11) { localObject2.addSuppressedException(localThrowable11); } else localFileWriter.close();  } } catch (Throwable localThrowable2) { } finally {
        if (localObject1 != null) try { localFileReader.close(); } catch (Throwable localThrowable12) { localObject1.addSuppressedException(localThrowable12); } else localFileReader.close();
      }
    } catch (IOException localIOException) {
      //この部分は、元コードのcatch節そのまま。
      localIOException.printStackTrace();
    }


うーん。try〜catchの五重ネストか・・・・。甘いシュガーシンタックスの下には泥臭い現実が待ち構えていた罠。

関係ないけど"boiler plate"って何?

元記事中で使われている"boiler plate"という表現。"定型文"的な意味で使われているのをちょくちょく見るけど、何故"boiler plate"が"定型文"となるのか調べてみた。いやただググってみただけなんだけど。

http://dictionary.reference.com/browse/boilerplate

Word Origin & History

boilerplate
newspaper (and now information technology) slang for "unit of writing that can be used over and over without change," 1893, from a literal meaning (1840) "metal rolled in large, flat plates for use in making steam boilers." The connecting notion is probably of sturdiness or reusability. From 1890s to 1950s it was literal: publicity items were cast or stamped in metal ready for the printing press and distributed to newspapers as filler. The largest supplier was Western Newspaper Union.
Online Etymology Dictionary, © 2010 Douglas Harper

適当訳

1893年、新聞(そして、現在は情報技術)で"何度も何度も変りなく使われる文章"を示すスラングで、"蒸気ボイラーを作成するために大きく平らに圧延された金属板"(1840年)という言葉から派生した。頑丈さや再利用性という意味のつながりがあるのだろう。
1890年代から1950年代までは、プレス印刷されて新聞の埋め草として配布されるために金属に鋳造もしくは刻印された広告という意味だった。最大の供給者はWestern Newspaper Union。


要は、"判で押したような"ってことか。