通过反射获取到抽象类或者接口中泛型信息的操作也是很常见的。实际上开发中,解析后台数据的Json数据,生成对应的泛型实体类,会用到反射获取泛型信息的操作。
实战案例
大致思路:
getGenericInterfaces()
获取到泛型接口的Type数组。getActualTypeArguments()
获取到泛型接口的实际类型。
1. 定义一个泛型的接口:
package com.xingen.classdemo.genericity;
/**
* Created by ${新根} on 2018/2/16 0016.
* 博客:http://blog.csdn.net/hexingen
*
* 参考:https://www.cnblogs.com/whitewolf/p/4355541.html
*/
public interface GenericityInterface<K,T> {
T doThing(K k);
}
2. 定义一个实现类,用于获取指定具体的类型
package com.xingen.classdemo.genericity;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
/**
* Created by ${新根} on 2018/2/16 0016.
* 博客:http://blog.csdn.net/hexingen
* <p>
* 反射获取泛型信息
*/
public class GenericityInterfaceImp implements GenericityInterface<String, Bean> {
//泛型中的两个类型
private Class<?> kClass,tClass;
public GenericityInterfaceImp() {
getGenericityMessage(GenericityInterfaceImp.class);
}
@Override
public Bean doThing(String s) {
return new Bean(s);
}
public void getGenericityMessage(Class<?> mClass) {
try {
//获取泛型接口
Type[] intefaceTypeArray = mClass.getGenericInterfaces();
if (intefaceTypeArray == null && intefaceTypeArray.length == 0) {
return;
}
//获取实现的第一个接口类型
Type type = intefaceTypeArray[0];
if (!(type instanceof ParameterizedType)) {
//这是Object类型
return;
}
//获取到实际的泛型中参数类型
Type[] parameterizedType = ((ParameterizedType) type).getActualTypeArguments();
kClass=TypeUtils.getClass(parameterizedType[0]);
tClass=TypeUtils.getClass(parameterizedType[1]);
}catch (Exception e){
e.printStackTrace();
}
}
public Class<?> getkClass() {
return kClass;
}
public Class<?> gettClass() {
return tClass;
}
public static GenericityInterfaceImp newInstance(){
return new GenericityInterfaceImp();
}
}
3. 定义一个工具类:用于Type和Class之间的转换。
package com.xingen.classdemo.genericity;
import java.lang.reflect.Type;
/**
* Created by ${新根} on 2018/2/16 0016.
* 博客:http://blog.csdn.net/hexingen
*
* 通过Type获取对象class
*/
public class TypeUtils {
private static final String TYPE_NAME_PREFIX = "class ";
public static String getClassName(Type type) {
if (type==null) {
return "";
}
String className = type.toString();
if (className.startsWith(TYPE_NAME_PREFIX)) {
className = className.substring(TYPE_NAME_PREFIX.length());
}
return className;
}
public static Class<?> getClass(Type type)
throws ClassNotFoundException {
String className = getClassName(type);
if (className==null || className.isEmpty()) {
return null;
}
return Class.forName(className);
}
}
4. 定义一个实体类:用于指定泛型中实际类型
public class Bean {
private String work;
public Bean() {
}
public Bean(String work) {
this.work = work;
}
public String getWork() {
return work;
}
public void setWork(String work) {
this.work = work;
}
}
5. 程序入口main()
,运行:
public class Client {
public static void main(String[] args) {
useGenericity();
}
/**
* 反射泛型信息
*/
public static void useGenericity(){
GenericityInterfaceImp imp=GenericityInterfaceImp.newInstance();
System.out.println("反射接口中泛型参数: K是 "+imp.getkClass().getName()+" T 是:"+imp.gettClass().getName());
}
}
6. 运行结果如下:
反射接口中泛型参数: K是 java.lang.String T 是:com.xingen.classdemo.genericity.Bean
本案例的项目代码: https://github.com/13767004362/JavaDemo/tree/master/ClassDemo