使用 Java 反射调用带有泛型参数的方法

Calling a method with an generic parameter with Java reflection

我需要调用此方法:public T unwrap(Class iface) 来自我无法导入的 class。

我正在尝试这样做:

 Class jbossWrappedSt = Class.forName("org.jboss.jca.adapters.jdbc.jdk6.WrappedPreparedStatementJDK6");

 Method metodoUnwrap = jbossWrappedSt.getDeclaredMethod ("unwrap", new Class[]{Class.class});
 Object val = metodoUnwrap.invoke (st, new Object[] {PreparedStatement.class});

但因 NoSuchMethodException 异常而失败:

java.lang.NoSuchMethodException: org.jboss.jca.adapters.jdbc.jdk6.WrappedPreparedStatementJDK6.unwrap(java.lang.Class)

Class java文档: https://repository.jboss.org/nexus/content/unzip/unzip/org/jboss/ironjacamar/jdbc-local/1.0.28.Final/jdbc-local-1.0.28.Final-javadoc.jar-unzip/org/jboss/jca/adapters/jdbc/JBossWrapper.html#unwrap%28java.lang.Class%29

更新:我忘了说我们正在使用 Java 1.5(是的!我知道)。

您要求的是 已声明 方法,该方法排除了接收 继承 方法的可能性。因此,如果 WrappedPreparedStatementJDK6JBossWrapper 或 class 层次结构中的其他 class 继承方法而不是自己声明它,查找将失败。您应该使用 getMethod,它会为您提供方法,而不管它在 class 层次结构中的何处定义,前提是该方法是 public,这里就是这种情况。

然而,由于它是在标准Java API Wrapper interface中定义的,因此根本不需要使用Reflection。如果 st 的编译时类型还不是 PreparedStatement,您可以简单地调用 ((Wrapper)st).unwrap(PreparedStatement.class).

Javadoc中的class是

org.jboss.jca.adapters.jdbc.JBossWrapper

但是您正在查看的 class 是不同的 class。

您正在查看的 class 没有解包方法。

https://repository.jboss.org/nexus/content/unzip/unzip/org/jboss/ironjacamar/jdbc-local/1.0.28.Final/jdbc-local-1.0.28.Final-javadoc.jar-unzip/org/jboss/jca/adapters/jdbc/jdk6/WrappedPreparedStatementJDK6.html

getDeclaredmethod 不像 getMethod 那样遵循继承层次结构来查找方法。

由于方法是public,我建议你使用getMethod,你不需要知道实际实现该方法的class。

事实上,您应该能够直接调用 public 方法,但我认为您必须使用反射是有原因的。