簡體   English   中英

如何從外部塊中重新拋出lambda塊中的異常?

[英]How can I re-throw an exception in a lambda block as from the outer block?

使用以下代碼,

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? //  --/
        }
    });
}

我怎么可以丟sce仿佛方法( supplier )方法把它扔?

請注意,上面的代碼只是一個例子。 我需要key(s.get())在lambda表達式中。

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

你不能。 Supplier#get()不會聲明拋出任何(已檢查)異常。 請記住,lambda表達式只是創建一個實例,它實際上並不調用目標功能接口方法。

如果您願意,可以將已檢查的異常包裝在未經檢查的異常中並拋出該異常。

如果要以安全的方式處理已檢查的異常,則需要一個輔助方法,該方法提供將異常包裝到RuntimeException子類型中的功能。 這是一個輔助函數,它使用Generic的類型安全性來確保只重新拋出聲明的異常(除非你使用不安全的操作):

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); }
    }));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM