我想獲得類或接口實現的泛型類型。我知道這有一些風險和怪癖,但我試圖理解什麼是可能的。在運行時獲取泛型:在某些情況下有效,但在其他情況下無效 - 爲什麼?
這裏是我的示例代碼:
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.LinkedList;
public class Main {
public interface MyInterface<T> {
}
public static class BaseImpl<T> implements MyInterface<T> {
}
public static class TypedImpl extends BaseImpl<Integer> {
}
public static void main(String[] args) throws Exception {
LinkedList<MyInterface<Integer>> instances = new LinkedList<>();
// 1. anonymous class from interface
instances.add(new MyInterface<Integer>() {
});
// 2. class extending interface
instances.add(new BaseImpl<Integer>());
// 3. class with pre-defined generic type
instances.add(new TypedImpl());
for (MyInterface<Integer> instance : instances) {
System.out.println("----------------------------------------------");
Class clazz = instance.getClass();
Type genericSuper = clazz.getGenericSuperclass();
Type[] genericInterfaces = clazz.getGenericInterfaces();
Class target = null;
System.out.println("class: " + clazz.getName());
System.out.println("generic super: " + genericSuper);
System.out.println("generic interfaces: " + Arrays.asList(genericInterfaces));
// attempt to 'extract' generic type
if (genericSuper instanceof ParameterizedType) {
target = getGeneric((ParameterizedType) genericSuper);
} else if (genericInterfaces.length > 0) {
for (Type genericInterface : genericInterfaces) {
if (genericInterface instanceof ParameterizedType) {
target = getGeneric((ParameterizedType) genericInterface);
if (null != target) {
break;
}
}
}
}
System.out.println("TARGET: " + target);
}
}
// attempt to get type argument
public static Class getGeneric(ParameterizedType type) {
if (MyInterface.class.isAssignableFrom((Class) type.getRawType())) {
Type typeArg = type.getActualTypeArguments()[0];
try {
return (Class) typeArg;
} catch (ClassCastException e) {
System.out.println("cast exception for '" + typeArg + "'");
}
}
return null;
}
}
的這個輸出是:
----------------------------------------------
class: Main$1
generic super: class java.lang.Object
generic interfaces: [Main.Main$MyInterface<java.lang.Integer>]
TARGET: class java.lang.Integer
----------------------------------------------
class: Main$BaseImpl
generic super: class java.lang.Object
generic interfaces: [Main.Main$MyInterface<T>]
cast exception for 'T'
TARGET: null
----------------------------------------------
class: Main$TypedImpl
generic super: Main.Main$BaseImpl<java.lang.Integer>
generic interfaces: []
TARGET: class java.lang.Integer
所以,我的目標是讓target
變量的值是Integer.class
。對於匿名類(#1)和顯式類型實現(#3),我能夠按預期找到目標。爲什麼它在這些情況下工作,而不是在#2(BaseImpl實例)的情況下工作?有沒有另外一種方法來完成這個? (我知道通過實現類的構造函數傳遞目標Class
共同解決方法的,但我感興趣的是動態做這個)
我已經諮詢了以下來源:
- Get type of a generic parameter in Java with reflection
- Get generic type of class at runtime
- How to get a class instance of generics type T
非常感謝提前,
阿貝爾
你似乎在尋找http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/ResolvableType解釋。 HTML – EpicPandaForce