文章目录
Java中的Type知多少?(下)
入门
从spring framework 4.0开始,spring引入了ResolvableType类来完成对java中Type的封装。
下面我基于spring提供的ResolvableType改写《Java中的Type知多少》上篇的所有示例。
ParameterizedType示例
public class TypeApplication{
public Map<String,Integer> field;
public static void main(String[] args) throws NoSuchFieldException {
//通过反射获取Field
Field field = TypeApplication.class.getField("field");
ResolvableType resolvableType = ResolvableType.forField(field);
//通过getGenerics方法获取泛型的实际类型
//key 和 value Type都被包装成ResolvableType
ResolvableType[] generics = resolvableType.getGenerics();
for(ResolvableType type : generics){
//通过resolve获取Class类型
Class actType = type.resolve();
//分别输出:
//class java.lang.String
//class java.lang.Integer
System.out.println(actType.toString());
}
}
}
GenericArrayType示例
public class TypeApplication{
public List<String>[] field;
public static void main(String[] args) throws NoSuchFieldException {
//通过反射获取Field
Field field = TypeApplication.class.getField("field");
ResolvableType resolvableType = ResolvableType.forField(field);
//判断是否是array
if(resolvableType.isArray()){
//如果是array,获取成分类型,成分类型也被包装成ResolvableType -> List<String>
ResolvableType componentType = resolvableType.getComponentType();
//获取List<String>中的String类型
ResolvableType[] generics = componentType.getGenerics();
for(ResolvableType type : generics){
Class actType = type.resolve();
//输出:
// class java.lang.String
System.out.println(actType);
}
}
}
}
TypeVariable示例
public class TypeApplication<T extends Number & Cloneable>{
public T field;
public static void main(String[] args) throws NoSuchFieldException {
//通过反射获取Field
Field field = TypeApplication.class.getField("field");
ResolvableType resolvableType = ResolvableType.forField(field);
Class boundType = resolvableType.resolve();
//这里比较遗憾,对于TypeVariable类型的resolve,我们只可以拿到bounds数组的[0]元素
//输出:
// class java.lang.Number
System.out.println(boundType.toString());
}
}
WildcardType
public class TypeApplication<T extends Number & Cloneable>{
public Map<? extends Number,? super String> field;
public static void main(String[] args) throws NoSuchFieldException {
//通过反射获取Field
Field field = TypeApplication.class.getField("field");
ResolvableType resolvableType = ResolvableType.forField(field);
//通过getGenerics获取map的key与value的类型:WildcardType,包装成ResolvableType
ResolvableType[] generics = resolvableType.getGenerics();
for(ResolvableType type : generics){
//分别resolve Key 与 Value的类型,有上界优先上界(如果上界是Object认为是无上界),无上界就是下界
//同样只能解析一个上界或下界
Class classType = type.resolve();
//分别输出:
// class java.lang.Number
// class java.lang.String
System.out.println(classType.toString());
}
}
}
如何构造ResolvableType
在上面的示例中我们通过forField构造ResolvableType,其实还可以通过以下方法构造
- forClass
通过Class构造 - forClassWithGenerics
通过Class加泛型类型构造 - forInstance
通过实例构造 - forField
通过Field构造 - forConstructorParameter
通过构造函数参数构造 - forMethodReturnType
通过方法返回类型构造 - forMethodParameter
通过方法参数构造 - forArrayComponent
通过成分类型构造array - forType
直接通过type构造
通过示例进一步了解ResolvableType
public class DemoApplication{
Map<String,BigDecimal> map;
public static void complex(List<Map<String,Double>> list){
}
public static void main(String[] args) throws NoSuchMethodException {
//通过field构造 ResolvableType
ResolvableType resolvableType = ResolvableType.forField(ReflectionUtils.findField(DemoApplication.class,"map"));
//输出:
//class java.lang.String
//class java.math.BigDecimal
for(ResolvableType t : resolvableType.getGenerics()){
System.out.println(t.resolve().toString());
}
//相当于构建了一个Map<Long,BigDecimal>的Type
resolvableType = ResolvableType.forClassWithGenerics(Map.class,Long.class,BigDecimal.class);
//输出:interface java.util.Map
System.out.println(resolvableType.resolve().toString());
//输出:
// class java.lang.Long
// class java.math.BigDecimal
for(ResolvableType t : resolvableType.getGenerics()){
System.out.println(t.resolve().toString());
}
ResolvableType stringToBigDecimalConvert = ResolvableType.forType(StringToBigDecimalConvert.class);
ResolvableType converter = ResolvableType.forType(Converter.class);
//true 相当于 Converter.class.isAssignableFrom(StringToBigDecimalConvert.class)
boolean ret = converter.isAssignableFrom(stringToBigDecimalConvert);
//来个复杂的
ResolvableType complex = ResolvableType.forMethodParameter(ReflectionUtils.findMethod(DemoApplication.class,"complex",List.class),0);
System.out.println(complex.resolve().toString());//输出:interface java.util.List
//取下double类型
ResolvableType doubleType = complex.getGeneric(0,1);
System.out.println(doubleType); //输出:java.lang.Double
}
}
更多内容,关注《超哥spring源码解析》