ラムダとデフォルトのメソッドインターフェースに関する新しいJava 8の機能に感謝します。それでも、私はまだチェックされた例外に飽きています。たとえば、オブジェクトのすべての表示フィールドを一覧表示するだけの場合は、単に次のように記述します。
Arrays.asList(p.getClass().getFields()).forEach(
f -> System.out.println(f.get(p))
);
ただし、get
メソッドはConsumer
インターフェイスコントラクトに同意しないチェック例外をスローする可能性があるため、その例外をキャッチして次のコードを記述する必要があります。
Arrays.asList(p.getClass().getFields()).forEach(
f -> {
try {
System.out.println(f.get(p));
} catch (IllegalArgumentException | IllegalAccessException ex) {
throw new RuntimeException(ex);
}
}
);
ただし、ほとんどの場合、例外をaとしてスローし、RuntimeException
コンパイルエラーなしで例外をプログラムに処理させるかどうかを許可します。
それで、私はチェックされた例外の迷惑のための私の物議を醸す回避策についてあなたの意見を持ちたいです。そのために、次のように補助インターフェイスConsumerCheckException<T>
とユーティリティ関数rethrow
(Dovalのコメントの推測に応じて更新)を作成しました。
@FunctionalInterface
public interface ConsumerCheckException<T>{
void accept(T elem) throws Exception;
}
public class Wrappers {
public static <T> Consumer<T> rethrow(ConsumerCheckException<T> c) {
return elem -> {
try {
c.accept(elem);
} catch (Exception ex) {
/**
* within sneakyThrow() we cast to the parameterized type T.
* In this case that type is RuntimeException.
* At runtime, however, the generic types have been erased, so
* that there is no T type anymore to cast to, so the cast
* disappears.
*/
Wrappers.<RuntimeException>sneakyThrow(ex);
}
};
}
/**
* Reinier Zwitserloot who, as far as I know, had the first mention of this
* technique in 2009 on the java posse mailing list.
* http://www.mail-archive.com/javaposse@googlegroups.com/msg05984.html
*/
public static <T extends Throwable> T sneakyThrow(Throwable t) {
throw (T) t;
}
}
そして今、私は書くことができます:
Arrays.asList(p.getClass().getFields()).forEach(
rethrow(f -> System.out.println(f.get(p)))
);
これがチェック例外を回避するのに最適なイディオムであるかどうかはわかりませんが、説明したように、チェック例外を処理せずに最初の例を達成するより便利な方法が欲しいです。これは私が見つけたより簡単な方法ですそれをするために。
sneakyThrow
insideを使用しrethrow
て元のチェック済み例外をスローできますRuntimeException
。あるいは、同じことを行うProject Lombokの@SneakyThrows
注釈を使用することもできます。
Consumer
s in forEach
は並列に実行される場合があることに注意してくださいStream
。コンシューマーのウィッシングから発生したスロー可能オブジェクトは、呼び出しスレッドに伝播します。1)同時に実行されている他のコンシューマーを停止せず、適切かどうかは不明です。スロー可能なオブジェクトの1つは、呼び出し元のスレッドに表示されます。