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が来ると吹っ飛ぶ。