簡體   English   中英

不會引發檢查的異常並將其轉換為RuntimeException

[英]Checked exception is not thrown and turned into RuntimeException

這是怎么回事

為什么IOException(RemoteException)的已檢查子級被轉換為RuntimeException?

這里摘錄的片段

import java.rmi.RemoteException;

class Thrower {
    public static void spit(final Throwable exception) {
        class EvilThrower<T extends Throwable> {
            @SuppressWarnings("unchecked")
            private void sneakyThrow(Throwable exception) throws T {
                throw (T) exception; // something interesting 
            }
        }
        new EvilThrower<RuntimeException>().sneakyThrow(exception);
    }
}

public class ThrowerSample {
    public static void main( String[] args ) {
        Thrower.spit(new RemoteException("go unchecked!"));
    }
}

這是怎么回事

這段代碼規避了異常的編譯時檢查

為什么它會有用?

使用使用已檢查異常的api並不總是很方便。

JDBC是最著名的例子之一。 使用jdbc總是需要開發人員處理SQLException 但是通常您不知道應該如何處理該異常。

或者,如果您使用的庫是開發人員決定從Exception而不是RuntimeException繼承其異常的庫。


為什么IOExceptionRemoteException )的已檢查子級被轉換為RuntimeException

它不會轉換為RuntimeException

拋出的異常是RemoteException

Exception in thread "main" java.rmi.RemoteException: go unchecked!

該代碼段使用Java泛型“技巧”。 如果沒有@SuppressWarnings("unchecked")行,編譯器將生成未經檢查的強制轉換警告。

拼圖43

該代碼段是Java Puzzlers的Puzzle 43的解決方案之一:陷阱,陷阱和極端案例

// Don’t do this - circumvents exception checking!
public static void sneakyThrow(Throwable t) {
    Thread.currentThread().stop(t); // Deprecated!!
}

無需使用任何不推薦使用的方法,就可以編寫一種功能與sneakyThrow等效的方法。 實際上,至少有兩種方法可以做到這一點。 其中之一僅在5.0版及更高版本中有效。 你可以寫這樣的方法嗎? 它必須用Java而不是JVM字節碼編寫。 客戶端編譯后,不得更改該方法。 您的方法不一定是完美的:如果它不能拋出Exception一個或兩個子類,則可以接受。

書中使用泛型的解決方案:

// Don’t do this either - circumvents exception checking!
class TigerThrower<T extends Throwable> {
    public static void sneakyThrow(Throwable t) {
        new TigerThrower<Error>().sneakyThrow2(t);
    }
    private void sneakyThrow2(Throwable t) throws T {
        throw (T) t;
    }
}

請注意這本書中的解決方案:

警告是編譯器告訴您您可能正在射擊自己的腳,實際上是這樣。 未經檢查的強制轉換警告告訴您在運行時不會檢查有問題的轉換。 當您收到未經檢查的強制轉換警告時,請修改程序以消除它,或者說服自己強制轉換不會失敗

總之,虛擬機不會強制執行Java的異常檢查。 它是一種編譯時工具,旨在簡化編寫正確程序的過程,但可以在運行時規避。 為了減少曝光,請不要忽略編譯器警告。


也可以看看:

@SneakyThrows

暫無
暫無

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

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