gpt4 book ai didi

Java - 为什么类型参数不能在 catch 子句中?

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:06:22 26 4
gpt4 key购买 nike

我知道泛型类型不能扩展 Throwable 并且我知道这没有意义,因为类型删除(仅在运行时抛出异常)和其他微妙的事情。

然而 Java 允许类型参数被 Throwable 限制实际上下面的代码是合法的

class MyClass<T extends Throwable> { /*body of the class */ }

在 catch 子句中使用 T 参数是非法的

try { //do something that throws exception //  }
catch(T e) /* ILLEGAL!!! DOESN'T COMPILE */ {}

我能理解这个约束的唯一原因是类型参数,因为删除,被它的边界类型所取代,在本例中是 Throwable。但是类型参数也可能受到不止一种边界类型的限制,所以我可能会遇到这种情况

class MyClass<T extends Object & Throwable> [*]

在这种情况下,T 在被 Object 删除后被替换,我知道 Object(不是 Throwable 类型) 变量不能在 catch 子句中。

如果这就是这个 Java 约束的原因,请告诉我。谢谢。

编辑:[*] 正如 davidxxx 让我注意到的,这个类声明无法编译,因为 Throwable 不是一个接口(interface)。

最佳答案

运行时无法检查捕获的异常类型是否与 T 匹配,因为它不知道 T 是什么。

参见 this question有关一些其他信息 - 类型参数保留在方法和类中,但不保留在变量中。

catch block 的要点是您可以通过为异常类型提供特定行为来处理异常。这也是为什么您可以为单个 try 提供多个 catch block 的原因。如果没有特定的异常类型,就不可能执行正确的 catch block 。

此外,如果您使用原始类型运行代码,您希望代码执行什么操作?您建议的方式 T 将替换为 Throwable 并且 catch block 现在将捕获 所有 异常而不是只有特定类型的那些。

另外,JLSCatchType 指定为:

CatchType:
ClassType
ClassType | CatchType

不包括 TypeArgument

如果您真的想要这样做,您可以捕获Throwable 并使用instanceof 或使用它的Class< 检查类型:

try {
doSomethingDangerous();
} catch (Throwable t) {
if (t instanceof IOException) {
handleIoException(t);
} else if (...) {
...
} else {
handleOther(t);
}
}

备注:Catching Throwable or Exception is usually considered very bad practice .

编辑:here's what it looks like in C# for possible reference .

关于Java - 为什么类型参数不能在 catch 子句中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45282776/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com