反射之获取类属性及对应数据篇
无敌的反射
这次是在日常中对反射的简单使用,==基本就是对类的反射,以及获取类的属性,以及通过数据对象获取相应字
段的值==,以便于更方便的使用,在自己使用的过程中所理解,反射应用的场景一般都是通用处理数据部分,大家在
做统一数据准备或者处理的时候,如果遇到相关的可以借鉴一下,如果有什么好建议可以留言,互相学习 互相进步。
反射获取类对象的属性及属性值
// datas 为List集合,不用指定泛型,通用处理list中对象
Map<String, String> map = new HashMap<>();
for (Object data : datas){
//遍历获取对象的Class
Class<?> aClass = data.getClass();
try {
//根据对象的Class获取对象的beanInfo对象
BeanInfo beanInfo = Introspector.getBeanInfo(aClass);
//使用BeanInfo 的getPropertyDescriptors()方法,获取当前对象data的 PropertyDescriptor类型数组,为了便于我自己使用,这里我直接转为List 集合,其中每个PropertyDescriptor对应data对象的每个属性
List<PropertyDescriptor> propertyDescriptors = Arrays.asList(beanInfo.getPropertyDescriptors());
//遍历PropertyDescriptor类型集合
for (PropertyDescriptor field : propertyDescriptors) {
String fieldName = field.getName();
// 过滤class属性,因为我需要的是类中的属性,用不到class相关信息,所以这里过滤掉了class相关内容,如果有需要可以放弃过滤,下面会附上过滤class相关的图片
if (fieldName.equals("class")) {
continue;
}
// 得到property对应的getter方法,getter相当于类中的getXXX()方法,用于获取data对象对应的field的值
Method getter = field.getReadMethod();
//如果当前字段类型为自定义类型,默认为成员内部类,特殊处理
//这里我自加判断当前PropertyDescriptor的类型是否为自定义类型,如果为自定义我要进一步去获取该自定义类中的字段,可以按自己需求去更改
if (!field.getPropertyType().getName().startsWith("java.")){
Class<?> fieldClass = field.getPropertyType();
Object value = getter.invoke(data);
//doBean为自定义方法,其实就是将该部分抽成一个方法为了处理数据时使用这一部分,大家视情况而定,下面会带上我自己简易版doBean方法
doBean(fieldClass, map,value,cacheData);
}else {
String dataValue = null;
//DATE_SET FALG_SET是自定义的静态set 用来存放我要单独处理的一些属性名,使用set而不使用list,是因为contains判是否包含时,set效率会更高
if (DATE_SET.contains(fieldName)){
LocalDateTime value = (LocalDateTime) getter.invoke(data);
//doDataFormat方法也是我自定义的一个格式化处理数据的方法,也会在下方将代码给大家,按需自取
dataValue = doDataFormat(value);
}else if (FALG_SET.contains(fieldName)){
Byte value = (Byte) getter.invoke(data);
dataValue = doDataFormat(value);
}
map.put(fieldName,dataValue);
}
} catch (IntrospectionException e) {
e.printStackTrace();
}
}
这里为过滤class部分的附图
doBean 方法相关代码
/**
* List数据处理主要逻辑
*
* @param aClass
* @param map
* @param data
*/
public static void doBean(Class<?> aClass, Map<String, String> map, Object data) {
Integer timeoutReasonId = null;
BeanInfo beanInfo = null;
try {
beanInfo = Introspector.getBeanInfo(aClass);
//获取当前对象data 类的 PropertyDescriptor 集合 对应每个字段
List<PropertyDescriptor> propertyDescriptors = Arrays.asList(beanInfo.getPropertyDescriptors());
for (PropertyDescriptor field : propertyDescriptors) {
String fieldName = field.getName();
// 过滤class属性
if (fieldName.equals("class")) {
continue;
}
// 得到property对应的getter方法
Method getter = field.getReadMethod();
//如果当前字段类型为自定义类型,默认为成员内部类,特殊处理
if (!field.getPropertyType().getName().startsWith("java.")) {
Class<?> fieldClass = field.getPropertyType();
Object value = getter.invoke(data);
doBean(fieldClass, map, value);
} else {
String dataValue = null;
//DATE_SET FALG_SET是自定义的静态set 用来存放我要单独处理的一些属性名,使用set而不使用list,是因为contains判是否包含时,set效率会更高
if (DATE_SET.contains(fieldName)) {
LocalDateTime value = (LocalDateTime) getter.invoke(data);
//doDataFormat方法也是我自定义的一个格式化处理数据的方法
dataValue = doDataFormat(value);
} else if (FALG_SET.contains(fieldName)) {
Byte value = (Byte) getter.invoke(data);
dataValue = doDataFormat(value);
}
map.put(fieldName,dataValue);
}
}
} catch (IntrospectionException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
throw new SystemNoLogException(ResponseCode.DATA_NOT_EXIST, e.getMessage());
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
doDataFormat 方法相关代码
// doDataFormat 方法部分,这里就展示俩个简单例子给大家,自己做的时候按需处理就好
/**
* LocalDateTime 格式处理
* @param time
* @return
*/
public static String doDataFormat(LocalDateTime time){
DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
return dtf2.format(time);
}
/**
* 处理0/1类型数据
* @param flag
* @return
*/
public static String doDataFormat(Byte flag){
//-1为缺省值 导出时置空
return flag==-1 ? "" : (flag ==0 ? "否" : "是");
}
赠送部分(没太大意义就是上边用到的静态Set)
// LocalDateTime 时间格式数据 处理为 yyyy-MM-dd HH:mm:ss 格式 的数据字段
private final static Set<String> DATE_SET = new HashSet<>(Arrays.asList("archivedTime","startTime", "discTime"));
// 值为 1/0 处理为 是/否 的数据字段
private final static Set<String> FALG_SET =new HashSet<>(Arrays.asList("installAMS", "downgrade", "hoException"));
简单的反射获取类属性的使用到这就结束了!!!