using のアレ
java.io.Closeable の事も忘れないであげて。 - 設計と実装の狭間で。 に対して、Syntax Sugarっぽいものを目指してみた。
public abstract class Using<S extends Closeable, T extends Throwable> { abstract S value() throws T; abstract void process(S value) throws T; void play() { new Or() { @Override void handle(T ignore) {} }.play(); } abstract class Or { abstract void handle(T thrown); void play() { S value = null; try { value = value(); process(value); } catch (Throwable thrown) { @SuppressWarnings("unchecked") T t = (T) thrown; handle(t); } finally { try { if (value != null) { value.close(); } } catch (IOException ignored) {} } } } }
利用例。
public static void main(String[] args) { new Using<InputStream, IOException>() { @Override InputStream value() throws IOException { return new FileInputStream("FILE"); } @Override void process(InputStream value) throws IOException { value.read(); } }.play(); new Using<InputStream, IOException>() { @Override InputStream value() throws IOException { return new FileInputStream("FILE"); } @Override void process(InputStream value) throws IOException { value.skip(1); } }.new Or() { @Override void handle(IOException thrown) { thrown.printStackTrace(); } }.play(); }
途中で違うんじゃないかとは薄々気づいてましたよ。
ちなみにcatchしてるところはまじめに書いてないので、RuntimeExceptionが来ると吹っ飛ぶ。