java反射field相关知识
Class c = ArrayList.class;
c.isPrimitive(); //判断c是否为基本数据类型
c.isAssignableFrom(List.class); //判断c是否是List类的子类或父类
c.getGenericType(); //得到泛型类型
一、判断指定class是否基础类型或者包装类型
方法一
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.9</version>
</dependency>
ObjectUtil.isBasicType
判断是否为基本类型,包括包装类型和原始类型。
包装类型:
- Boolean
- Byte
- Character
- Double
- Float
- Integer
- Long
- Short
原始类型:
- boolean
- byte
- char
- double
- float
- int
- long
- short
boolean basicType = ObjectUtil.isBasicType(a);
二、普通类型的变量直接field.getType()即可以获取到他们的类型
Class type = field.getType();
assertEquals(type,String.class);
三、数组类型
数组类型不像其他的类型可以通过isAssignableFrom()函数来进行判断,他需要使用isArray() 来判断该type是否是一个数组类型,然后使用getComponentType() 获取他的元素的类型
Class> type = field.getType();
//一般来说,判断是否是某种类型是可以使用isAssignableFrom
// 判断是否是数组类型比较特殊,要使用isArray()这个函数
if (type.isArray()){
//获得数组的类型,使用getComponentType()这个方法
Class componentType = type.getComponentType();
assertEquals(componentType,Integer.class);
}
四、带泛型的类型
带泛型的类型就是类似于List这样的类型,我们现在的任务就是获取到String这个类型。
ParameterizedType表示参数化的类型,例如Collection这样的类型。我们可以通过getGenericType()方法获得该子类,当你的类型带有参数的时候就会返回ParameterizedType,否则会返回普通的类型(class)
Class<T> tc = T.class;
Field[] fields = tc.getDeclaredFields();
for (Field f : fields) {
Class fc = f.getType();
//判空
if (fc == null){
continue;
}
if(fc.isPrimitive()){
System.out.println("基本数据类型: " + f.getName() + " " + fc.getName());
}else{
if(fc.isAssignableFrom(List.class)){ //判断是否为List
System.out.println("List类型:" + f.getName());
//如果是List类型,得到其Generic的类型
Type gt = f.getGenericType();
//判断是否泛型类型,例:List list = new ArrayList();这种会为false
if(gt instanceof ParameterizedType){
ParameterizedType pt = (ParameterizedType)gt;
Class lll = (Class)pt.getActualTypeArguments()[0];
System.out.println("\t\t" + lll.getName());
}
}
}
}
五、复杂嵌套
如果我们有一个嵌套List,我们想拿到嵌套在最里面的类型,那么我们可以这么做呢?
//其实我们可以使用递归的思想去获得最里面的类型
Field field = Some.class.getDeclaredField("matrix");
assertEquals(getBaseType(field.getGenericType()),Double.class);
public static Type getBaseType(Type genericReturnType){
Objects.requireNonNull(genericReturnType);
//如果出入的type是ParameterizedType并且是List类型则进入递归便利
//第二个是将传入的类型转换为ParameterizedType类型,然后getRawType即自己的类型,强转为class类型后进行对比
if (genericReturnType instanceof ParameterizedType &&
List.class.isAssignableFrom((Class)(((ParameterizedType) genericReturnType).getRawType()))){
Type[] actualTypeArguments = ((ParameterizedType)genericReturnType).getActualTypeArguments();
Type type = actualTypeArguments[0];
return getBaseType(type);
}else{
return genericReturnType;
}
}
六、多个泛型参数
Field field = Some.class.getDeclaredField("map");
Type type = field.getGenericType();
if (type instanceof ParameterizedType){
ParameterizedType parameterizedType = (ParameterizedType)type;
Type[] actualTypes = parameterizedType.getActualTypeArguments();
assertEquals(actualTypes[0],String.class);
assertEquals(actualTypes[1],Class.class);
}else{
throw new IllegalStateException();
}
站在巨人肩膀上摘苹果
https://blog.csdn.net/weixin_39590601/article/details/114359916
https://blog.csdn.net/weixin_43831204/article/details/107670994