献给所有辛勤耕耘的小伙伴们,致敬勤劳勇敢的翔哥,加油!
1.环境
- SpringBoot
- JDK1.8
2.代码
反射类:ReFlectUtil
package com.reflect;
import org.springframework.util.CollectionUtils;
import java.lang.reflect.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class ReFlectUtil {
public static void main(String[] args) {
List<Person> list = new ArrayList<>();
Person person = new Person();
person.setId(1);
person.setName("张三");
person.setAddress1(null);
person.setAddress2("null");
person.setAddress3("NuLl");
person.setAddress4("大连");
person.setAge(20L);
list.add(person);
person = new Person();
person.setId(2);
person.setName("张三");
person.setAddress1(null);
person.setAddress2("北京");
person.setAddress3("NuLl");
person.setAddress4("大连");
person.setAge(30L);
list.add(person);
// List处理
List<Person> personList = getList(list);
System.out.println(personList);
// 对象处理
//Person p = getObject(person);
//System.out.println(p);
}
/**
* 将对象中String类型变量 值为null的处理成“”
*
* @param object
* @param <T>
* @return T
*/
public static <T> T getObject(T object) {
try {
T instance = (T) object.getClass().newInstance();
constructNewInstance(object, instance);
return instance;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将List中String类型变量 值为null的处理成“”
*
* @param list
* @param <T>
* @return List<T>
*/
public static <T> List<T> getList(List<T> list) {
try {
List<T> resultList = new ArrayList<>();
for (T object : list) {
T instance = (T) object.getClass().newInstance();
constructNewInstance(object, instance);
resultList.add(instance);
}
return resultList;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 1.将旧对象中的值取出,处理后放入新的对象
* 2.不需要处理的值,直接取出放入新的对象
*
* @param object
* @param instance
* @param <T>
* @throws NoSuchMethodException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
private static <T> void constructNewInstance(T object, T instance) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
Field[] allFields = getAllFields(object.getClass());
Field[] filterList = filterField(allFields);
for (Field declaredField : filterList) {
declaredField.setAccessible(true);
if (declaredField.getType() == String.class) {
// 调用get方法,拿到字段的值用于下方进行判断
Method method = object.getClass().getDeclaredMethod("get" + declaredField.getName().substring(0, 1).toUpperCase() + declaredField.getName().substring(1));
Object value = method.invoke(object);
// 判断当String类型变量的值是null、"null"、"NULL"时,调用set方法将值赋成空字符串""
if (null == value || value.toString().toLowerCase().contains("null")) {
Method m = instance.getClass().getDeclaredMethod("set" + declaredField.getName().substring(0, 1).toUpperCase() + declaredField.getName().substring(1), new Class[]{String.class});
m.invoke(instance, "");
} else {
Method m = instance.getClass().getDeclaredMethod("set" + declaredField.getName().substring(0, 1).toUpperCase() + declaredField.getName().substring(1), new Class[]{String.class});
m.invoke(instance, value);
}
}
if (declaredField.getType() == int.class) {
Method method = object.getClass().getDeclaredMethod("get" + declaredField.getName().substring(0, 1).toUpperCase() + declaredField.getName().substring(1));
Object value = method.invoke(object);
if (null == value || value.toString().toLowerCase().contains("null")) {
Method m = instance.getClass().getDeclaredMethod("set" + declaredField.getName().substring(0, 1).toUpperCase() + declaredField.getName().substring(1), new Class[]{int.class});
m.invoke(instance, 0);
} else {
Method m = instance.getClass().getDeclaredMethod("set" + declaredField.getName().substring(0, 1).toUpperCase() + declaredField.getName().substring(1), new Class[]{int.class});
m.invoke(instance, value);
}
}
if (declaredField.getType() == Long.class) {
Method method = object.getClass().getDeclaredMethod("get" + declaredField.getName().substring(0, 1).toUpperCase() + declaredField.getName().substring(1));
Object value = method.invoke(object);
if (null == value || value.toString().toLowerCase().contains("null")) {
Method m = instance.getClass().getDeclaredMethod("set" + declaredField.getName().substring(0, 1).toUpperCase() + declaredField.getName().substring(1), new Class[]{Long.class});
m.invoke(instance, 0L);
} else {
Method m = instance.getClass().getDeclaredMethod("set" + declaredField.getName().substring(0, 1).toUpperCase() + declaredField.getName().substring(1), new Class[]{Long.class});
m.invoke(instance, value);
}
}
}
}
/**
* 反射获取所有的字段
*
* @param clasz
* @return Field[]
*/
private static Field[] getAllFields(Class clasz) {
List<Field> fieldList = new ArrayList<>();
while (clasz != null) {
fieldList.addAll(new ArrayList<>(Arrays.asList(clasz.getDeclaredFields())));
clasz = clasz.getSuperclass();
}
Field[] fields = new Field[fieldList.size()];
fieldList.toArray(fields);
return fields;
}
/**
* 过滤字段 将final、static、abstract修饰的字段过滤掉
*
* @param fields
* @return Field[]
*/
private static Field[] filterField(Field[] fields) {
List<Field> tempList = Arrays.stream(fields).filter(field -> null != field
&& !Modifier.isFinal(field.getModifiers())
&& !Modifier.isStatic(field.getModifiers())
&& !Modifier.isAbstract(field.getModifiers())).collect(Collectors.toList());
int arrLength = CollectionUtils.isEmpty(tempList) ? 1 : tempList.size();
Field[] resultArr = new Field[arrLength];
if (!CollectionUtils.isEmpty(tempList)) {
tempList.toArray(resultArr);
}
return resultArr;
}
}
实体类:Person
package com.reflect;
public class Person {
private int id;
private String name;
private Long age;
private String address1;
private String address2;
private String address3;
private String address4;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getAge() {
return age;
}
public void setAge(Long age) {
this.age = age;
}
public String getAddress1() {
return address1;
}
public void setAddress1(String address1) {
this.address1 = address1;
}
public String getAddress2() {
return address2;
}
public void setAddress2(String address2) {
this.address2 = address2;
}
public String getAddress3() {
return address3;
}
public void setAddress3(String address3) {
this.address3 = address3;
}
public String getAddress4() {
return address4;
}
public void setAddress4(String address4) {
this.address4 = address4;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", address1='" + address1 + '\'' +
", address2='" + address2 + '\'' +
", address3='" + address3 + '\'' +
", address4='" + address4 + '\'' +
'}';
}
}
3.代码介绍
ReFlectUtil类中是核心功能代码工具类,里面主要功能是getList和getObject方法,分别是对集合和对象中String xxx = null 处理成 String xxx = "",其中还包含一个main方法方便对代码进行测试。
Person是自定义的一个实体类,为了方便测试getList和getObject方法而提供。
对于CSV和PDF生成,要求所有字段都定义成String类型,拿Integer举例,对于byte(位)、short(短整数)、int(整数)、long(长整数)、float(单精度)、double(双精度)、char(字符)和boolean(布尔值)这8中基本数据类型,如果用包装类可以赋成null(如:Integer xxx = null;),但是赋成""就会出现类型不匹配的问题,java反射中会出现同样的问题,如果不用包装类会有默认值(如:int xxx = 0;),不符合业务要求。
ReFlectUtil类中constructNewInstance方法,对于int.class和Long.class是为了代码举例的完整性而分别列举了一个int基本数据类型和一个包装类Long,并无实际意义。对于String.class的判断是真实功能需要。
4.代码效果演示
对于List处理:
控制台输出结果证明:address1、 address2、 address3无论是null空对象,还是字符串"null"都被成功处理成了空字符串""
对于Object的处理
控制台输出结果证明:address1、 address2、 address3无论是null空对象,还是字符串"null"都被成功处理成了空字符串""