一、场景分析
java 中没有 python 一样的方法,通过属性名称直接获取属性值。
python
getattr(obj, name[, default]) : 访问对象的属性。
getattr(student, 'name')
java 中有 Map, 可以实现类似功能,但是如果我们现在有一个对象,要通过Map的方式获取属性值,还得先将对象转成Map,这需要借助一些JSON工具。java 中能依赖的,就只有反射了。
java
map.get("name")
java 原生的反射接口都太繁琐,而且还得捕获各种异常。借助 spring ReflectionUtils 工具可以帮我们快速地实现这种功能。
二、代码实现
假设有这么一个学生对象 Student,它关联一个课程对象 Course。
java
package com.study.student.entity;
import lombok.Data;
@Data
public class Student {
private String name;
private Course course;
}
----------------------------------------
package com.study.student.entity;
import lombok.Data;
@Data
public class Course {
private String name;
private Integer credit;
}
通过属性名称获取属性对象:
java
package com.study.utils;
import com.study.student.entity.Course;
import com.study.student.entity.Student;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;
/**
* 反射工具
*/
public class ReflectionUtil {
/**
* 获取目标对象 target.fieldName 的属性值
* @param clazz 目标对象 Class 类型
* @param fieldName 属性名
* @param target 目标对象
* @return 属性值
*/
public static Object getValueByFieldName(Class<?> clazz, String fieldName, Object target) {
// 从 clazz 中获取 fieldName 属性名对应的 Field 对象
Field field = ReflectionUtils.findField(clazz, fieldName);
// 判空
Assert.notNull(field, "field must not be null");
// 设置访问权限
ReflectionUtils.makeAccessible(field);
// 反射获取
return ReflectionUtils.getField(field, target);
}
public static void main(String[] args) {
Student student = new Student();
Course course = new Course();
course.setName("高等数学");
course.setCredit(10);
student.setName("小林");
student.setCourse(course);
Course course1 = (Course) ReflectionUtil.getValueByFieldName(Student.class, "course", student);
System.out.println(course1);
}
}
输出:
Course(name=高等数学, credit=10)