繁体   English   中英

反射无法获取从泛型接口重写的方法的实际参数类型?

[英]Reflection can't get the actual parameter type of a method that overrides from a generic-typed interface?

编辑:对不起,我在下面提供的示例无法重现该问题...我正在尝试找到重现此问题的正确方法。 在此之前,您可能会忽略我的问题...

通常我们会像这样获取方法的参数类型:

Class<?> clazz = method.getParameterTypes()[0]

我以前从未三思而后行,但最近遇到一个问题,即这样做时我总是得到class java.lang.Object 经过检查,我发现案件可以这样描述:

/** A parameterized interface */
public interface IService<T> {

    Result create(T obj);
}

/** An implementation */
public class CarService implements IService<Car> {

    public Result create(Car car) { ... }
}

然后,当我使用上述方法获取参数car的类时,结果证明它是一个class java.lang.Object

Method methods = CarService.class.getMethods();
for (Method method : methods) {
    Class<?>[] types = method.getParameterTypes();
    // when the loop meets "create" here ...
}

我想我完全忘记了有关类型擦除的一些基本知识? 但是现在,如果可能的话,在这种情况下,我真的需要获取实际的参数类型。

是的,这是令人讨厌的类型擦除。 值得一看的是您在这里的字节码中得到了什么:

class Car {}
interface IService<T> {
    void create(T obj);
}

class CarService implements IService<Car> {
    public void create(Car car) {}
}

然后:

$ javac Test.java # Contains all the above...
$ javap -c CarService

Compiled from "Test.java"
class CarService implements IService<Car> {
  CarService();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public void create(Car);
    Code:
       0: return

  public void create(java.lang.Object);
    Code:
       0: aload_0
       1: aload_1
       2: checkcast     #2                  // class Car
       5: invokevirtual #3                  // Method create:(LCar;)V
       8: return
}

使用反射时也会显示这些内容:

public class Test {
    public static void main(String[] args) {
        Method[] methods = CarService.class.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method.getName());
            for (Class<?> type : method.getParameterTypes()) {
                System.out.printf("- %s%n", type.getName());
            }
        }
    }
}

输出:

create
- Car
create
- java.lang.Object

如何使用它取决于您要实现的目标,但是希望知道字节码中有多种方法将有所帮助...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM