前言
实际开发中,泛型使用到处可见。有时候定义接口时,经常使用泛型,而不是指定具体对象,使用泛型的好处很多,特别是代码复用方面。要获取类或接口上的泛型类型Class<?>,然后对这个类型进行数据处理,至于怎么处理,还要看实际的应用场景。本篇讲述如何获取类或接口的泛型类型(参数化类型ParameterizedType
)。
实例
1.定义泛型接口
public interface Response<T> {
void onSuccess(T data);
}
2.定义泛型类
public static class BaseResponse<T> {
}
3.定义测试类和测试方法
测试类
public static class SubResponse extends BaseResponse<Person> {
}
public static class Person {
public String name;
}
测试方法
private static void test(SubResponse subResponse) {
Class<?> clz = getClassT(subResponse, 0);
System.out.println(clz.getSimpleName());
}
private static void test(Response a) {
Class<?> clz = getInterfaceT(a, 0);
System.out.println(clz.getSimpleName());
}
4.调用
test(new Response<Person>() {
@Override
public void onSuccess(Person data) {
}
});
test(new Response<List<Person>>() {
@Override
public void onSuccess(List<Person> data) {
}
});
test(new SubResponse());
5.输出结果
上面输出都是Person
这个clz 就是person的Class,有了这个Class,可以做你想做的事情,比如:根据Class实例化对象、或者结合Class把json字符串和xml字符串转化成具体的bean,然后再返回调用处。
获取类或接口上的泛型类型T完整代码
/**
* 获取接口上的泛型T
*
* @param o 接口
* @param index 泛型索引
*/
public static Class<?> getInterfaceT(Object o, int index) {
Type[] types = o.getClass().getGenericInterfaces();
ParameterizedType parameterizedType = (ParameterizedType) types[index];
Type type = parameterizedType.getActualTypeArguments()[index];
return checkType(type, index);
}
/**
* 获取类上的泛型T
*
* @param o 接口
* @param index 泛型索引
*/
public static Class<?> getClassT(Object o, int index) {
Type type = o.getClass().getGenericSuperclass();
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
Type actType = parameterizedType.getActualTypeArguments()[index];
return checkType(actType, index);
} else {
String className = type == null ? "null" : type.getClass().getName();
throw new IllegalArgumentException("Expected a Class, ParameterizedType"
+ ", but <" + type + "> is of type " + className);
}
}
private static Class<?> checkType(Type type, int index) {
if (type instanceof Class<?>) {
return (Class<?>) type;
} else if (type instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) type;
Type t = pt.getActualTypeArguments()[index];
return checkType(t, index);
} else {
String className = type == null ? "null" : type.getClass().getName();
throw new IllegalArgumentException("Expected a Class, ParameterizedType"
+ ", but <" + type + "> is of type " + className);
}
}
小结
本篇讲述了如何获取类或接口上的泛型类型,实际要灵活使用。上面的Type是Java语言中所有类型的公共父接口。Type有四个子类——ParameterizedType
、 TypeVariable
、GenericArrayType
、WildcardType
。在Gson等框架中有出现,有空的话,大家可以研究一下用法。