サンプル
public interface Agent extends AutoCloseable{ public void execute(); }
public class AgentImpl implements Agent{ @Override public void execute(){ System.out.println("AgentImpl::execute"); } @Override public void close() throws Exception{ System.out.println("AgentImpl::close"); } }
通常、 try(Agent a = new AgentImpl()){ と書くところを try(a) だけにして
Agent a = new AgentImpl(); try(a){ a.execute(); }catch(Exception e){ e.printStackTrace(); }finally{ System.out.println("finally !!"); }
とすることができます。どちらも実行結果は
AgentImpl::execute AgentImpl::close finally !!
AutoCloseable を継承するインターフェースで、
close の throws Exception を外して
再定義すれば、
public interface Agent extends AutoCloseable{ public void execute(); public void close(); }
public class AgentImpl implements Agent{ @Override public void execute(){ System.out.println("AgentImpl::execute"); } @Override public void close(){ System.out.println("AgentImpl::close"); } }
try()~ で catch Exception しなくて済みます。
Agent a = new AgentImpl(); try(a){ a.execute(); }finally{ System.out.println("finally !!"); }
Exception でばなく特定の例外で同様に close で throw を指定できるわけで、
それが、java.io.CloCloseable に該当するのですね。
public interface Closeable extends AutoCloseable { public void close() throws IOException; }
インターフェースで、例外を throws 宣言してるからこそ、
開発IDE でコーディング時に、try-with-resources 文を書くように
警告してくれるんですね。
こんなコードをしょっちゅう書きますが、
ByteArrayOutputStream も外に書くスタイルなら close の後で toString() を書けるわけです。
private String readResiurceFile(String path) { ByteArrayOutputStream bo = new ByteArrayOutputStream(); try(InputStream in = getClass().getClassLoader().getResourceAsStream(path); bo){ byte[] b = new byte[1024]; int n = 0; while((n=in.read(b, 0, b.length)) > 0) { bo.write(b, 0, n); } bo.flush(); }catch(IOException e){ e.printStackTrace(); } return bo.toString(); }