2015-01-12 14 views
6

ラムダブロック内の例外を外側のブロックから再スローする方法はありますか?次のコードで

void key(Key) throws SomeCheckedException { 
} 

void supplier(Supplier<Key> s) throws SomeCheckedException { 
    ofNullable(s).ifPresent(s -> {     // | 
     try {          // | 
      key(s.get());       // | 
     } catch (final SomeCheckedException sce) { // | 
      // sce is coming from key() method  // | 
      // How can I throw sce for outer method? // --/ 
     } 
    }); 
} 

方法(supplier)メソッドがそれを投げているsceかのようにどのようにして投げることができますか?

上記のコードは単なる例であることに注意してください。ラムダ式の中に入れるにはkey(s.get())が必要です。

void supplier(Supplier<Key> s) throws SomeCheckException { 
    key(s.get()); 
} 
+2

のようなヘルパーメソッドの型呼び出しを使用することができます。私はそのキー(...)がチェック例外をスローするとは思わなかった。しかし、[私の答え](http://stackoverflow.com/a/27900544/2711488)もそのケースを処理します。 – Holger

答えて

2

チェック例外を安全に処理したい場合は、サブタイプRuntimeExceptionに例外をラップするヘルパーメソッドが必要です。ここでは(あなたが危険な操作を使用しない限り)のみ宣言例外が再スローされることを保証するためにジェネリックの型の安全性を使用して、このようなヘルパー関数です:

public static <E extends Throwable> void attempt(
    Consumer<Function<E,RuntimeException>> action) throws E { 

    final class CarryException extends RuntimeException { 
     final E carried; 
     CarryException(E cause) { 
      super(cause); 
      carried=cause; 
     } 
    } 

    try { action.accept(CarryException::new); } 
    catch(CarryException ex) { throw ex.carried; } 
} 

それはない機能を受け取ることになります任意のactionをサポートしていますチェックされた例外タイプをRuntimeExceptionに一時的にラップします。このラッピングは透明になり、メソッドattemptは正常に完了するか、元のチェック例外E(または、発生した場合は無関係のチェックされていない例外)をスローします。

だから、このようにそれを使用することができます:コンパイラが自動的に例外タイプを推測することができないため、ネストされた操作に

public static void processIterm(Supplier<Key> s) 
    throws SomeCheckedException { 

    attempt((Function<SomeCheckedException, RuntimeException> thrower) -> 
     Optional.ofNullable(s).ifPresent(nonNull -> { 
      try { key(nonNull.get()); } // assuming key may throw SomeCheckedException 
      catch(SomeCheckedException e) { throw thrower.apply(e); } 
     })); 
} 

。上のコードは、throwerパラメータ型の明示的な宣言を使用しています。代わりに、

ContainingClass.<SomeCheckedException>attempt(thrower -> 
    Optional.ofNullable(s).ifPresent(nonNull -> { 
     try { key(nonNull.get()); } 
     catch(SomeCheckedException e) { throw thrower.apply(e); } 
    })); 
7

できません。 Supplier#get()は、(チェックされた)例外をスローすることを宣言しません。ラムダ式は単にインスタンスを作成するだけで、実際にはターゲットの機能インターフェイスメソッドを呼び出さないことに注意してください。

チェックした例外を未チェックの例外にラップしてスローすることができます。

関連する問題