java泛型的一些研究

来源:互联网 发布:网络赌搏 编辑:程序博客网 时间:2024/05/16 19:33

    java在1.5版本引入了泛型(参数化类型),极大的方便了一些操作,使代码更加简洁。当然在泛型引入后,java反射机制也变得更加复杂化,这里就分享一些我对java泛型的研究。

    获取泛型的方式:

field.getGenericType();//获得字段的泛型method.getGenericParameterTypes();//获得方法参数的泛型method.getGenericReturnType();//获得方法返回参数的泛型method.getGenericExceptionTypes();//获得异常参数的泛型class.getGenericInterfaces();//获得实现接口的泛型class.getGenericSuperclass();//获得父类的泛型...//待补充

    已上所有获得泛型的方法返回的都是java.lang.reflect.Type,这个类有5个子类:ParameterizedType、GenericArrayType、WildcardType、TypeVariable、Class,以下一一说明这些子类是代表的什么。

    1、ParameterizedType:有泛型的类型,举个例子:

public class Test14 {    Map<Integer, String> map;     public static void main(String[] args) {        try {            Field field = Test14.class.getDeclaredField("map");            Type type = field.getGenericType();//获得该字段的泛型            //已知map字段是一个java.util.Map且后面带有泛型,所以该Type是一个ParameterizedType            System.out.println("type instanceof ParameterizedType = " + (type instanceof ParameterizedType));            if (type instanceof ParameterizedType) {                ParameterizedType parameterizedType = (ParameterizedType) type;                Type[] types = parameterizedType.getActualTypeArguments();                for (Type type1 : types) {                    System.out.println(type1.getTypeName());                }            }        } catch (NoSuchFieldException e) {            e.printStackTrace();        }    }}    //输出结果:type instanceof ParameterizedType = truejava.lang.Integerjava.lang.String
 2、GenericArrayType:有泛型的类型且是数组,举个例子:

public class Test14 {    Map<Integer, String>[] map;     public static void main(String[] args) {        try {            Field field = Test14.class.getDeclaredField("map");            Type type = field.getGenericType();//获得该字段的泛型            //已知map字段是一个后面带有泛型的java.util.Map且是数组,所以该Type肯定是一个GenericArrayType            System.out.println("type instanceof GenericArrayType = " + (type instanceof GenericArrayType));            if (type instanceof GenericArrayType) {                GenericArrayType genericArrayType = (GenericArrayType) type;                Type type1 = genericArrayType.getGenericComponentType();                System.out.println(type1);            }        } catch (NoSuchFieldException e) {            e.printStackTrace();        }    }}  //输出结果:type instanceof GenericArrayType = truejava.util.Map<java.lang.Integer, java.lang.String>

    3、WildcardType,还需研究。

    4、TypeVariable,还需研究。

    5、Class,就是正常的class,不带泛型的。

    当一个参数极端化时比如下面这个:

Map<String, Map<String, String[]>[]>[] map

解析起来会非常麻烦,我写了一个解析类,希望大家可以提出意见

public class ClassWithGenericType {    private Boolean isArray = false;    private String thisClass;    private ClassWithGenericType[] genericType;     public Boolean getIsArray() {        return isArray;    }     public void setIsArray(Boolean isArray) {        this.isArray = isArray;    }     public String getThisClass() {        return thisClass;    }     public void setThisClass(String thisClass) {        this.thisClass = thisClass;    }     public ClassWithGenericType[] getGenericType() {        return genericType;    }     public void setGenericType(ClassWithGenericType[] genericType) {        this.genericType = genericType;    }     public static ClassWithGenericType parseType(Type type) {        ClassWithGenericType cwgt = new ClassWithGenericType();        if (type instanceof GenericArrayType) {//有泛类型且是数组            GenericArrayType genericArrayType = (GenericArrayType) type;            cwgt = parseType(genericArrayType.getGenericComponentType());            cwgt.setIsArray(true);        } else if (type instanceof ParameterizedType) {            ParameterizedType parameterizedType = (ParameterizedType) type;            cwgt = parseType(parameterizedType.getRawType());            Type[] types = parameterizedType.getActualTypeArguments();            ClassWithGenericType[] cwgts = new ClassWithGenericType[types.length];            for (int i = 0; i < types.length; i++) {                Type actualType = types[i];                cwgts[i] = parseType(actualType);            }            cwgt.setGenericType(cwgts);            cwgt.setIsArray(false);         } else if (type instanceof WildcardType) {//TODO 需要研究            return cwgt;        } else if (type instanceof TypeVariable) {//TODO 需要研究            return cwgt;        } else if (type instanceof Class) {//无泛类型            Class clazz = (Class) type;            if (clazz.isArray()) {//数组类型                cwgt.setIsArray(true);                cwgt.setThisClass(clazz.getComponentType().getName());            } else {                cwgt.setIsArray(false);                cwgt.setThisClass(clazz.getName());            }        }         return cwgt;    }     @Override    public String toString() {        StringBuilder sb = new StringBuilder();        sb.append(thisClass);        if (genericType != null && genericType.length > 0) {            sb.append("<");            StringBuilder sb2 = new StringBuilder();            for (ClassWithGenericType classWithGenericType : genericType) {                sb2.append(", ").append(classWithGenericType.toString());            }            sb.append(sb2.substring(2));            sb.append(">");        }        if (isArray)            sb.append("[]");        return sb.toString();    }     public String toJSON() {        return JSONObject.fromObject(this).toString();    }     public static ClassWithGenericType parseJson(String json) {        JSONObject jsonObject = JSONObject.fromObject(json);        return (ClassWithGenericType) JSONObject.toBean(jsonObject, ClassWithGenericType.class);    }}

试验一下Map<String, Map<String, String[]>[]>[] map解析:

public class Test15 {    Map<String, Map<String, String[]>[]>[] map;     public static void main(String[] args) {        try {            Field field = Test15.class.getDeclaredField("map");            Type type = field.getGenericType();            System.out.println(ClassWithGenericType.parseType(type));        } catch (NoSuchFieldException e) {            e.printStackTrace();        }    }}//输出结果:java.util.Map<java.lang.String, java.util.Map<java.lang.String, java.lang.String[]>[]>[]

可以看到已经全部解析出来了。但是这个解析类还有一些问题:

1、extends 和 super 有问题,如下:

List<? extends TestBean> list1;List<? super TestBean> list2;//这一类的应该在WildcardType和TypeVariable中处理

2、在泛型继承的情况下有问题,如下:
public class Result<T> {   private Pager pager;   private List<T> list ;    public Pager getPager() {      return pager;   }    public void setPager(Pager pager) {      this.pager = pager;   }    public List<T> getList() {      return list;   }    public void setList(List<T> list) {      this.list = list;   }    public Result(Pager pager, List<T> list) {      this.pager = pager;      this.list = list;   }   public Result(){   }}//----public static void main(String[] args) {    try {        Field field = Result.class.getDeclaredField("list");        Type type = field.getGenericType();        System.out.println(ClassWithGenericType.parseType(type));    } catch (NoSuchFieldException e) {        e.printStackTrace();    }}//----//输出结果java.util.List<null>


0 0
原创粉丝点击