java - 在java中抛出通用异常

标签 java generics exception polymorphism try-catch

我有另一个来自 javaDeathMatch 游戏的具有挑战性的问题; 在下面的代码中,我们被询问下面的代码有什么样的问题。 如果我错了,请纠正我; 编译错误:无;在编译时,类型参数的删除还没有发生,动态绑定(bind)也没有发生,所以传递给 SQLException 类型方法的参数被认为是方法“pleaseThrow”中的异常,它(我的意思是Exception not SQLException) 在方法中被转换为 Runtime Exception 而没有错误。唯一的错误是我们没有合适的 catch 子句来捕获异常。

public class Exption<T extends Exception> {
    public static void main(String[] args) {
        try {
            new Exption<RuntimeException>().pleaseThrow(new SQLException());
        }catch (final SQLException ex){
            ex.printStackTrace();
        }
    }
    private void pleaseThrow(final Exception t) throws T{
        throw (T)t;
    }
}

如果我们用这个替换 catch 子句:

catch(final RuntimeException e){
    e.printStackTrace();
    System.err.println("caught");
}

异常将被捕获,但 System.err.println("caught") 永远不会被打印!!!什么问题????

最佳答案

这是由于类型删除。在编译后的 java 中,所有通用信息都会丢失(还有一些东西,但与此无关)。这意味着在编译期间,通用变量 T 等于 RuntimeException。所以你的 pleaseThrow 代码看起来像这样:

private void pleaseThrow(final Exception t) throws RuntimeException{
    throw (RuntimeException)t;
}

虽然在编译之后,每个泛型参数都被删除为基类型。在您的情况下,Exception。这给您留下了这样的方法签名:

private void pleaseThrow(final Exception t) throws Exception{
    throw (Exception)t;
}

终于清楚了,为什么您的 catch block 永远不会到达。您正试图捕获 RuntimeExceptions 但您实际抛出的是一个已检查的异常。然后向上传播并最终被 JVM 捕获。

Additional reading: Oracle Tutorial on type erasure

关于java - 在java中抛出通用异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51097975/

相关文章:

java - 安卓/Java : Simulate a click on this webpage

java - 找不到 DDMS 文件/opt/android-sdk-linux/platform-tools/hprof-conv ubuntu

java - 让Java函数对象封装泛型函数的正确方法

typescript - 将 TypeScript 的 InstanceType 泛型与抽象类一起使用?

java - freemarkers 跳过 assertNotNull InvalidReferenceException

java - 如何更改自动生成的 SOAP :address from a JAX-WS webservice WSDL deployed with Spring

java - Oauth 2 spring RestTemplate 使用刷新 token 登录

scala - Scala 的类型删除如何用于更高种类的类型参数?

java - 可以在 ArrayList 上设置和调用,抛出 UnsupportedException

java - 由于库项目资源丢失,应用程序在运行时崩溃