notepad.exe

つまり覚え書き

Javaのtry-catchを1行で書きたかったのでクラスを作ってみた

こんなことを思った

Javaにあるtry-catch文なんですが、例えばこんな処理を書くとします。 (funcが例外を起こす可能性のある処理だとします)

String str;
try {
    str = func();
catch (Exception e) {
   str = "hoge";
}

これ長くないですか?こう書きたくないですか?

String str = Try(func()).catchThenReturn(Exception.class, "hoge");

とりあえず書いてみる

処理が値を返すか返さないかで大きく変わってしまうのでとりあえずは値を返すものを対象にします。
まずはResultクラスを定義してその中に結果と例外をまとめるようにします。そして値を取り出すときはunwrap()を呼ぶ形にします。 ここまでの単純なところだけだとこんな感じ。

Resultクラス

class Result<R> {
    R r;
    Throwable e;

    public R unwrar() {
        return this.r;
    }
}

Tryクラスでの実行部分

class Try<T, R> {
    public Result<R> eval(T t, ThrowableFunction<T, R> func) {
        try {
            return new Result<>(func.apply(t));
        }catch (Throwable e) {
            return new Result<>(e);
        }
    }
}

これでとりあえず1行で書けるようになったのであとは例外を拾うためのメソッドを定義します。
例外を拾うメソッド自体もResultクラスを返すようにしておけば複数の例外に対処できそうな感じ。

public Result<R> catchThenReturn(Class<? extends Throwable> clazz, R t) {
        return new Result<>(equals(clazz) ? t : this.r, this.e);
    }

    private boolean equals(Class<? extends Throwable> clazz) {
        return this.e.getClass().getName().equals(clazz.getName());
    }
}

というわけでtry-catchをこんな感じで1行で書くことができました。

String ans = new Try<String, String>().eval("hoge", func).catchThenReturn(Hoge.class, "aaa").unwrap();

全体像

これです。Try.java · GitHub

new しないと使えなかったり、値を返さない場合のチェーンがやりにくかったりと問題は山ほどありますが、 なんとなく満足したので、これはこれで置いておきます。