亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用重新拋出異常的異常處理程序有什么明顯的區別

使用重新拋出異常的異常處理程序有什么明顯的區別

守著星空守著你 2023-05-17 16:00:15
給定一個可能拋出的函數:public static int f() throws Exception {    // do something}這段代碼有什么辦法:public static int catchF() throws Exception {    try {        return f();    } catch (Exception ex) {        throw ex;    }}和直接打電話有什么不同嗎f?即調用者可以通過檢查異常來檢測差異嗎?catchF使用而不是有任何明顯的開銷嗎f?如果沒有區別,編譯器或 JVM 能否將對的調用優化catchF為對的直接調用f?雖然這看起來像是一件奇怪的事情,但用例是在先前隱藏異常之后在類型級別重新引入異常:class Test {    // Hide the exception.    public static <X extends Exception, T> T throwUnchecked(Exception ex) throws X {        throw (X) ex;    }    // Interface for functions which throw.    interface Throws<T, R, X extends Exception> {        R apply(T t) throws X;    }    // Convert a function which throws a visible exception into one that throws a hidden exception.    public static <T, R, X extends Exception> Function<T, R> wrap(Throws<T, R, X> thrower) {        return t -> {            try {                return thrower.apply(t);            } catch(Exception ex) {                return throwUnchecked(ex);            }        };    }    // Unhide an exception.    public static <R, X extends Exception> R unwrap(Supplier<R> supp) throws X {        try {            return supp.get();        } catch (Exception ex) {            throw (X)ex;        }    }    public static Stream<Integer> test(Stream<String> ss) throws NumberFormatException {        return Test.<Stream<Integer>, NumberFormatException>unwrap(                () -> ss.map(wrap(Integer::parseInt))        );    }    public static void main(String[] args) throws NumberFormatException {        final List<Integer> li = test(Arrays.stream(new String[]{"1", "2", "3"})).collect(toList());        System.out.println(li);    }}目的是將拋出異常的函數包裝到在類型級別隱藏異常的函數中。這使得異??捎糜诶缌?。
查看完整描述

2 回答

?
皈依舞

TA貢獻1851條經驗 獲得超3個贊

與直接調用 f 有什么不同嗎?

不。

即調用者可以通過檢查異常來檢測差異嗎?

不,因為此時您沒有構造新的異常。堆棧跟蹤是在調用的位置構建的new WhateverException(...)不是在調用位置的位置throw,盡管它們通常位于同一位置)。

通常,如果由于異常而需要進行一些清理,則可以重新拋出捕獲的異常:

try {

? // ...

} catch (SomeException e) {

? // Clean up resources.

? throw e;

}

調用堆棧展開時發生的事情對調用者來說既不可見也不相關。

快速演示可以顯示堆棧跟蹤是相同的,無論異常是被捕獲并重新拋出還是僅僅允許傳播。

使用 catchF 而不是 f 是否有任何明顯的開銷?

構造異常的開銷將遠遠超過此冗余構造的任何開銷。


查看完整回答
反對 回復 2023-05-17
?
ibeautiful

TA貢獻1993條經驗 獲得超6個贊

簡單地重新拋出并且不影響異常的已知類型的異常處理程序絕對沒有語義效果。

那么,理論上,編譯器或 JVM 可以優化 try-catch out。在實踐中,我懷疑他們這樣做,因為這樣的代碼應該很少見并且不在熱路徑上(永遠不應該有例外);實現這樣的優化可能不值得付出努力。


查看完整回答
反對 回復 2023-05-17
  • 2 回答
  • 0 關注
  • 164 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號