java泛型的一些研究

    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 = true
java.lang.Integer
java.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 = true
java.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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值