[英]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.