Skip to content

Instantly share code, notes, and snippets.

@pfmiles
Last active January 22, 2017 12:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pfmiles/18b92ad65b7e80c9ea32c1dfede5fd0c to your computer and use it in GitHub Desktop.
Save pfmiles/18b92ad65b7e80c9ea32c1dfede5fd0c to your computer and use it in GitHub Desktop.
取得指定类的指定类型的直接父类或父接口身上实际传入的泛型实参列表
package test;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author pf-miles Dec 15, 2016 2:36:51 PM
*/
public class ClassUtil {
/**
* Maps primitive {@code Class}es to their corresponding wrapper {@code Class}.
*/
private static final Map<Class<?>, Class<?>> primitiveWrapperMap = new HashMap<Class<?>, Class<?>>();
static {
primitiveWrapperMap.put(Boolean.TYPE, Boolean.class);
primitiveWrapperMap.put(Byte.TYPE, Byte.class);
primitiveWrapperMap.put(Character.TYPE, Character.class);
primitiveWrapperMap.put(Short.TYPE, Short.class);
primitiveWrapperMap.put(Integer.TYPE, Integer.class);
primitiveWrapperMap.put(Long.TYPE, Long.class);
primitiveWrapperMap.put(Double.TYPE, Double.class);
primitiveWrapperMap.put(Float.TYPE, Float.class);
primitiveWrapperMap.put(Void.TYPE, Void.TYPE);
}
/**
* Maps wrapper {@code Class}es to their corresponding primitive types.
*/
private static final Map<Class<?>, Class<?>> wrapperPrimitiveMap = new HashMap<Class<?>, Class<?>>();
static {
for (final Class<?> primitiveClass : primitiveWrapperMap.keySet()) {
final Class<?> wrapperClass = primitiveWrapperMap.get(primitiveClass);
if (!primitiveClass.equals(wrapperClass)) {
wrapperPrimitiveMap.put(wrapperClass, primitiveClass);
}
}
}
public static boolean isPrimitiveOrWrapper(Class<?> type) {
if (type == null) {
return false;
}
return type.isPrimitive() || isPrimitiveWrapper(type);
}
public static boolean isPrimitiveWrapper(final Class<?> type) {
return wrapperPrimitiveMap.containsKey(type);
}
/**
* 取得指定类的指定类型的直接父类或父接口身上实际传入的泛型实参列表;未做任何cache工作
* @param cls 指定类
* @param genericType 指定的直接父类类型
* @return 指定的直接父类类型身上的泛型实参列表
* @throws BumonitorSdkException
*/
public static List<Class<?>> getDirectSuperClsActualGenericTypeArguments(Class<?> cls,
Class<?> genericType) throws BumonitorSdkException {
String errMsg = "No actual generic type arguments found. Target class: " + cls.getName()
+ ", generic super class(or interface): " + genericType.getName() + ".";
List<Class<?>> ret = new ArrayList<Class<?>>();
try {
// 先检查直接父类
Type superClsType = cls.getGenericSuperclass();
if (superClsType != null && superClsType instanceof ParameterizedType
&& ((ParameterizedType) superClsType).getRawType().equals(genericType)) {
for (Type gt : ((ParameterizedType) superClsType).getActualTypeArguments())
ret.add((Class<?>) gt);
return ret;
}
// 再检查直接父接口
Type[] itypes = cls.getGenericInterfaces();
if (itypes != null && itypes.length != 0)
for (Type t : itypes)
if (t instanceof ParameterizedType
&& ((ParameterizedType) t).getRawType().equals(genericType)) {
for (Type gt : ((ParameterizedType) t).getActualTypeArguments())
ret.add((Class<?>) gt);
return ret;
}
} catch (Exception e) {
throw new BumonitorSdkException(errMsg, e);
}
throw new BumonitorSdkException(errMsg);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment