AutoCloseable と try-with-resources 文について。

サンプル

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();
}