java - 在java中抛出通用异常
问题描述
我有另一个来自 javaDeathMatch 游戏的具有挑战性的问题;在下面的代码中,我们被问到下面的代码有什么样的问题。如果我错了,请纠正我;编译错误:无;在编译时,类型参数的擦除还没有发生,动态绑定还没有发生,所以传递给 SQLException 类型的方法的参数在方法“pleaseThrow”中被认为是异常,它(我的意思是Exception not SQLException) 在方法中被强制转换为运行时异常,没有错误。唯一的错误是我们没有适当的 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 块永远不会到达。你试图捕捉RuntimeExceptions
,但你实际上抛出的是一个检查异常。然后向上传播并最终被 JVM 捕获。
补充阅读:Oracle 类型擦除教程
推荐阅读
- azure - 需要将 Grafana 与 Azure 数据湖集成的解决方案
- node.js - 如何在 Mongoose 中重用 MongoClient?
- sql - 如何在没有科学记数法的情况下将 bigint 作为 nvarchar 存储在 SQL Server 表中?
- javascript - ReferenceError:e2e 测试中未定义窗口
- java - 带有 SpringBoot 的 SOAP:寻址到错误 URI 的 Soap 请求被神奇地重定向到其他端点 impl
- android - 使用 ButterKnife 在 Dialog 中定义的 Button 的空对象引用
- mysql - mysql - 无效的复制时间戳
- python - 需要有关 WebDriverWait text_to_be_present_in_element_value 的帮助
- json - 是否可以使用 siddhi 中的 json 映射删除封闭元素?
- c++ - 如何检查某个内存地址是否可用于 C++?