space.chensheng.wsmessenger.common.util.ReflectUtil Maven / Gradle / Ivy
The newest version!
package space.chensheng.wsmessenger.common.util;
import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
public class ReflectUtil {
public static Class> findGenericType(Object object, Class> parameterizedSuperclass, String typeParamName) {
if (object == null) {
return null;
}
Class> thisClass = object.getClass();
Class> currentClass = thisClass;
for (;;) {
if (currentClass.getSuperclass() == parameterizedSuperclass) {
int typeParamIndex = -1;
TypeVariable>[] typeParams = currentClass.getSuperclass().getTypeParameters();
for (int i = 0; i < typeParams.length; i ++) {
if (typeParamName.equals(typeParams[i].getName())) {
typeParamIndex = i;
break;
}
}
if (typeParamIndex < 0) {
throw new IllegalStateException(
"unknown type parameter '" + typeParamName + "': " + parameterizedSuperclass);
}
Type genericSuperType = currentClass.getGenericSuperclass();
if (!(genericSuperType instanceof ParameterizedType)) {
return Object.class;
}
Type[] actualTypeParams = ((ParameterizedType) genericSuperType).getActualTypeArguments();
Type actualTypeParam = actualTypeParams[typeParamIndex];
if (actualTypeParam instanceof ParameterizedType) {
actualTypeParam = ((ParameterizedType) actualTypeParam).getRawType();
}
if (actualTypeParam instanceof Class) {
return (Class>) actualTypeParam;
}
if (actualTypeParam instanceof GenericArrayType) {
Type componentType = ((GenericArrayType) actualTypeParam).getGenericComponentType();
if (componentType instanceof ParameterizedType) {
componentType = ((ParameterizedType) componentType).getRawType();
}
if (componentType instanceof Class) {
return Array.newInstance((Class>) componentType, 0).getClass();
}
}
if (actualTypeParam instanceof TypeVariable) {
// Resolved type parameter points to another type parameter.
TypeVariable> v = (TypeVariable>) actualTypeParam;
currentClass = thisClass;
if (!(v.getGenericDeclaration() instanceof Class)) {
return Object.class;
}
parameterizedSuperclass = (Class>) v.getGenericDeclaration();
typeParamName = v.getName();
if (parameterizedSuperclass.isAssignableFrom(thisClass)) {
continue;
} else {
return Object.class;
}
}
return null;
}
currentClass = currentClass.getSuperclass();
if (currentClass == null) {
return null;
}
}
}
}