80,472
社区成员




public static class A<T>{}
public static class B<I> extends A<String> {}
public static class C extends B<Integer> {}
//... 在 main 方法中
C c = new C();
//String.class
Class clazz = ReflectionUtil.getGenericClassSupportInterface(c.getClass(), A.class, 0);
//Integer.class
Class claz2 = ReflectionUtil.getGenericClassSupportInterface(c.getClass(), B.class, 0);
public class ReflectionUtil {
/**
* ## 支持获取接口泛型
* owner: A.class, target: B.class
* 获取类B上声明的第 index 个泛型的在 类 A 中的实际类型
* @param owner (子类)泛型的拥有者
* @param index target声明的位置从左到右数第 index 个泛型 如泛型<A, B> A对应index=1, B对应index=2
* @param target (父类)声明泛型的类, target 必须是 owner 的父类
* 例如:
* class<T> B{
* public Class getGenericClass(){
* return ReflectHelper.getGenericClass(getClass(), B.class, 0);
* }
* }
* class A extends B<String>{
*
* }
* class C extends B<Integer>{
*
* }
* class D<A> extends B<A>{
*
* }
*
* System.out.println(new A().getGenericClass() instanceOf String.class);
* System.out.println(new C().getGenericClass() instanceOf Integer.class);
* System.out.println(new D<Double>().getGenericClass() instanceOf Double.class);
* 打印结果为:
* true
* true
* false
*/
public static<T> Class getGenericClassSupportInterface(@NonNull Class<? extends T> owner, @NonNull Class<T> target, int index){
if(owner == target)
return null;
if(!target.isAssignableFrom(owner))
return null;
TypeVariable<Class<T>>[] tps = target.getTypeParameters();
if(index >= tps.length)
return null;
class Cache{
private Cache(Class clazz) {
this.clazz = clazz;
}
private Cache(Class clazz, int index) {
this.clazz = clazz;
this.index = index;
}
@NonNull
@Override
public String toString() {
return clazz.getName() + "-@-" + index;
}
private Class clazz;
private int index = 0;
}
LinkedList<Cache> classes = new LinkedList<>();
classes.add(new Cache(owner));
Class nextClazz = owner;
outside:
while (true){
Class superClazz = nextClazz.getSuperclass();
if(superClazz == target)
break;
if(superClazz != null && target.isAssignableFrom(superClazz)){
classes.add(new Cache(superClazz));
}else {
Class[] interfaces = nextClazz.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
Class interfaca = interfaces[i];
if(interfaca == target)
break outside;
if(target.isAssignableFrom(interfaca)){
classes.add(new Cache(interfaca, i));
superClazz = interfaca;
break;
}
}
}
nextClazz = superClazz;
if(superClazz == null)
break;
}
Cache cache = classes.removeLast();
Class supClazz = cache.clazz;
Type typeVar;
Class last = target;
if(last.isInterface()){
typeVar = ((ParameterizedType) supClazz.getGenericInterfaces()[cache.index]).getActualTypeArguments()[index];
}else {
typeVar = ((ParameterizedType) supClazz.getGenericSuperclass()).getActualTypeArguments()[index];
}
if(typeVar instanceof Class)
return (Class) typeVar;
if(typeVar instanceof ParameterizedType){
Type rawType = ((ParameterizedType) typeVar).getRawType();
if(rawType instanceof Class){
return (Class) rawType;
}
}
while (!classes.isEmpty()) {
System.out.println(cache);
index = Util.indexOf(supClazz.getTypeParameters(), typeVar, new Util.Comparator<TypeVariable, Type>() {
@Override
public boolean equals(TypeVariable left, Type right) {
if(left == right)
return true;
if(left == null || right == null)
return false;
if(!(right instanceof TypeVariable))
return false;
String leftName = left.getName();
String rightName = ((TypeVariable) right).getName();
return leftName.equals(rightName);
}
});
last = supClazz;
cache = classes.removeLast();
supClazz = cache.clazz;
System.out.println(cache + "___");
if(last.isInterface()){
typeVar = ((ParameterizedType) supClazz.getGenericInterfaces()[cache.index]).getActualTypeArguments()[index];
}else {
typeVar = ((ParameterizedType) supClazz.getGenericSuperclass()).getActualTypeArguments()[index];
}
if(typeVar instanceof Class)
return (Class) typeVar;
}
return null;
}
static class Util{
//获取数组 array 中 object 的角标
public static <L, R> int indexOf(L[] array, R object, @NonNull Comparator<L, R> comparator) {
if (array == null)
return -1;
for (int i = 0; i < array.length; i++) {
if (comparator.equals(array[i], object))
return i;
}
return -1;
}
interface Comparator<L, R> {
boolean equals(L left, R right);
}
}
}