从catch块的结果调用具有泛型参数的Java方法

从catch块的结果调用具有泛型参数的Java方法,java,generics,exception,try-catch,catch-block,Java,Generics,Exception,Try Catch,Catch Block,我遇到了一个意想不到的问题,涉及异常捕获和签名中的Java泛型。无需进一步说明,所讨论的代码(解释如下): 然后测试失败-即异常被标识为运行时异常,调用方法的非泛型,因此生成的ResultWrapper具有填充的exc 这对我来说完全是莫名其妙的。我相信,即使在catch(Exception e)子句中,e仍保留其原始类型(并记录消息System.out.println(e.getClass().getSimpleName()表明这是真的)&那么如何更改“类型”是否覆盖泛型方法签名?调用的方法由

我遇到了一个意想不到的问题,涉及异常捕获和签名中的Java泛型。无需进一步说明,所讨论的代码(解释如下):

然后测试失败-即
异常
被标识为
运行时异常
,调用
方法的非泛型
,因此生成的
ResultWrapper
具有填充的
exc


这对我来说完全是莫名其妙的。我相信,即使在
catch(Exception e)
子句中,
e
仍保留其原始类型(并记录消息
System.out.println(e.getClass().getSimpleName()
表明这是真的)&那么如何更改“类型”是否覆盖泛型方法签名?

调用的方法由参数的静态类型定义

  • 如果捕获到一个
    异常
    ,则静态类型为
    异常
    , 它不是
    RuntimeException
    的子类,因此 调用(对象)
。(回想一下,
T
在 汇编)
  • 在捕获
    RuntimeException
    的情况下,静态类型为
    RuntimeException
    ,由于它确实适合(RuntimeException)
  • ,因此会调用更具体的方法
    
    请注意,
    e.getClass().getSimpleName()
    提供的是动态类型,而不是静态类型。动态类型在编译过程中是未知的,而调用的方法是在编译过程中选择的

    下面是一个更简单的代码,演示了相同的问题:

    public static void foo(Object o) { 
        System.out.println("foo(Object)");
    }
    public static void foo(Integer n) { 
        System.out.println("foo(Integer)");
    }
    public static void main (String[] args) throws java.lang.Exception {
        Number x = new Integer(5);
        foo(x);
        System.out.println(x.getClass().getSimpleName());
    }
    
    在这里,调用方法
    foo(Object)
    ,即使
    x
    是一个
    Integer
    ,因为编译时已知的
    x
    的静态类型是
    Number
    ,而不是
    Integer
    的子类

    // i.e. explicitly catch RuntimeException, not Exception
    } catch (RuntimeException e) {
        return WrapperBuilder.of(e)
    }
    
    public static void foo(Object o) { 
        System.out.println("foo(Object)");
    }
    public static void foo(Integer n) { 
        System.out.println("foo(Integer)");
    }
    public static void main (String[] args) throws java.lang.Exception {
        Number x = new Integer(5);
        foo(x);
        System.out.println(x.getClass().getSimpleName());
    }