为什么我不能在java中抛出或捕获泛型类的实例?

J.z*_*hou 5 java generics

我知道我不能在Java中抛出或捕获泛型类的实例,例如,下面的代码编译错误:

public static <T extends Throwable> void test(Class<T> t){
    try{
        //do work
    }
    catch (T e){// ERROR--can't catch type variable
    Logger.global.info(...)
    }
}
Run Code Online (Sandbox Code Playgroud)

有人能解释Java禁止抛出或捕获泛型类实例的确切原因吗?

Mar*_*eel 4

您无法捕获一般异常,因为 Java 语言规范明确禁止它。在14.20 的 try 语句中它说:

如果在异常参数的类型表示中使用类型变量,则会出现编译时错误。

本节没有解释原因,但最相似的原因是被<T extends Throwable>删除为Throwable,因此您的代码实际上会被编译为:

public static void test(Class<? extends Throwable> t){
    try{
        //do work
    }
    catch (Throwable e){
    Logger.global.info(...)
    }
}
Run Code Online (Sandbox Code Playgroud)

这不是您的代码所表达的意图(很可能不是您想要的),因此语言规范明确禁止它。

请注意,允许抛出通用异常,但这通常仅在对另一个抛出异常的方法进行包装的情况下才相关。