如果你已经学过java反射技术很久了,但却不知道什么时候该用它,或者在实际编码中怎么用它,不妨看下接下来的文章,作为参考。
场景一:组装对象实体固定字段,比如你的系统使用了多张数据库表,每个数据库表对应一个对象,但每张表都会有固定的字段需要赋值,比如版本号,创建人,创建人编号,创建时间,修改人,修改人编号,修改时间等。在组装实体的时候需要重复给这些对象实体的固定字段通过set方法赋值,很麻烦。此时就可以通过反射封装一个方法,每次组装实体时调用该方法即可。
/**
user是当前登录用户
封装的赋值方法,只要含有这些字段的对象都可以直接调用
*/
public void setValue(Serializable obj, User user) {
//获取Class对象
Class clazz =obj.getClass();
try {
// 根据方法名获取指定set方法
Method setCratDt = clazz.getMethod("setCratDt", Date.class);
Method setCratUserCod = clazz.getMethod("setCratUserCod", String.class);
Method setCratUserNam = clazz.getMethod("setCratUserNam", String.class);
Method setVersion = clazz.getMethod("setVersion", Double.class);
//反射调用set方法赋值
setCratDt.invoke(obj, new Date());
setCratUserCod.invoke(obj, user.getUserId());
setCratUserNam.invoke(obj, user.getUserName());
setVersion.invoke(obj, 1.000d);
} catch (Exception e) {
e.printStackTrace();
}
}
}
场景二:JSON报文转对象,调用接口获取对象是个json字符串,我们需要把里面的字段转成java对象,方便后续处理。
//responseJson为接口返回值
public Student jsonToStudent(String responseJson){
responseJson = "{name:'zhangsan',age:'12'}";
//将jsonStr转成jsonObject
JSONObject obj = JSONObject.fromObject(responseJson);
Class clazz = Student.class;
Student student = (Student)clazz.newInstance();
Field[] fields = clazz.getDeclaredFields();
for(Feild feild:fields){
feild.setAccessible(true);
String fieldNam = feild.getName();
//手动拼对象类的属性的set方法
Method method = clazz.getMethod("set"+fieldNam,String.class);
method.invoke(student,obj.getString(fieldNam));
}
return student;
}
场景三:获取枚举类的值列表 ,比如有一个大枚举类,存的系统内所有枚举,你需要在枚举类里获取需要的枚举值列表作为前端下拉框的值,就可以使用该方法,只要传入枚举名即可获得该枚举下对应code的name(中文描述)。
//parmCod内部枚举类名称
public static String[] getAllOption(String parmCod){
//获取整个枚举类Class对象
Class<Enum> c = (Class<Enum>)Class.forName("com.test.constant.ResultEnum");
//获取枚举类内部类Class对象数组
Class innerClass[] = c.getDeclaredClasses();
int i = 0;
//遍历匹配要查找的内部枚举类
for (Class c1:innerClass) {
if (c.isEnum()){
String simpleName = c1.getSimpleName();
if (simpleName.equals(parmCod)){
Enum[] enums = c.getEnumConstants();
Method getName = c.getMethod("getName",String.class);
String[] arr = new String[enums.length];
//将匹配到的枚举类的cod对应的nam存入数组
for (Enum enum1:enums){
String fieldNam = getName.invoke(enum1);
arr[i] = fieldNam;
i++;
}
return arr;
}
}
}
return null;
}
场景四:excel导入数据时给对应实体字段赋值 ,比如你导入一个excel文件,在处理文件时需要把excel的列映射成数据库表对应对象的字段值。
//伪代码片段,遍历所有行
for(int r=1;r<totalRows.length;r++){
Row row = sheet.getRow(r);
Student student = new Student();
Field[] fields = student.getClass().getDeclaredFeilds();
for(int i=1;i<fields.length;i++){
Field f = fields[i];
f.setAccessible(true);
//获取第r行第i个单元格,反射赋值给student第i个字段
Cell cell = row.getCell(i-1);
try{
f.set(student,cell.getStringCellValue());
}catch(Exection e){
e.printStackTrace();
}
}
}
场景五:给具有特殊特征的字段赋值,比如你有一张宽表,冗余了很多备用字段,字段命名为txt_feld1,txt_feld2,txt_feld3,txt_feld4。就可以在一个for循环里直接通过反射赋值。
//伪代码如下
//声明一个指针变量
int j = 1;
Student student = new Student();
List<String> vluList = new ArrayList<>();
vluList.add("a");
vluList.add("b");
vluList.add("c");
vluList.add("d");
for(String item:vluList){
student.getClass().getMethod("setTxt_feld"+j,String.class).invoke(student,item);
j++;
}