Vin*_*Vin 3 java generics try-catch
我知道泛型类型不能扩展Throwable,我知道这没有意义,因为类型擦除(异常只在运行时抛出)和其他微妙的东西.
但是,Java允许类型参数受Throwable限制,实际上以下代码是合法的
class MyClass<T extends Throwable> { /*body of the class */ }
Run Code Online (Sandbox Code Playgroud)
什么是非法的是T在catch子句中使用参数
try { //do something that throws exception // }
catch(T e) /* ILLEGAL!!! DOESN'T COMPILE */ {}
Run Code Online (Sandbox Code Playgroud)
我能理解这个约束的唯一原因是,在这种情况下,type参数,因为擦除,被它的边界类型所取代Throwable.但是类型参数也可能受到多个边界类型的限制,所以我可能会遇到这种情况
class MyClass<T extends Object & Throwable> [*]
Run Code Online (Sandbox Code Playgroud)
在这种情况下T,在擦除之后被替换,Object并且我知道Object(不是类型Throwable)变量不能在catch子句中.
如果这是Java约束的原因,请告诉我.谢谢.
编辑:[*]由于davidxxx让我注意到,这个类声明不编译,因为Throwable它不是一个接口.
运行时无法检查捕获的异常的类型是否匹配,T因为它不知道是什么T.
有关其他信息,请参阅此问题 - 类型参数保留在方法和类中,但不保存在变量上.
A的得分catch块,你可以通过向异常类型提供特定行为处理异常.这也是catch为单个提供多个块的原因try.如果没有特定的异常类型,则无法执行正确的catch块.
此外,如果您使用原始类型运行代码,您希望代码做什么?您提出的方式T将被替换为,Throwable并且catch块现在将捕获所有异常,而不仅仅是某种类型的异常.
此外,JLS指定CatchType为:
CatchType:
ClassType
ClassType | CatchType
Run Code Online (Sandbox Code Playgroud)
不包括TypeArgument.
如果你真的想这样做,你可以Throwable使用instanceof或使用它来捕获并检查类型Class:
try {
doSomethingDangerous();
} catch (Throwable t) {
if (t instanceof IOException) {
handleIoException(t);
} else if (...) {
...
} else {
handleOther(t);
}
}
Run Code Online (Sandbox Code Playgroud)
注意:捕捉Throwable或Exception通常被认为是非常糟糕的做法.
编辑:这是C#中的可能参考.