一、简述
在Java的类class中,通常属性都是会进行封装的,会对外暴露setter,getter方法。可以通过setter或者getter方法去对属性进行赋值,或读取属性的值。
现在,我们需要动态调用setter和getter方法,要通过外部输入的方式来实现这个过程,那么有什么方式可以做到呢?
二、解决方案
2.1、PropertyUtils实现
PropertyUtils是commons-beanutils库提供的一个工具类,可快速适配使用动态调用setter以及getter方法,只需要名称即可,不需要处理过多的Bug。
引入相关依赖包:
<!--commons工具包-->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
PropertyUtils有两个方法,一个是setProperty,一个是getProperty。
通过setProperty或getProperty方法调用了指定属性的setter/getter方法:
//方法三:PropertyUtils的方式
User user=new User();
//通过name动态设置属性值
PropertyUtils.setProperty(user,"username","小李");
//过name动态获取属性值
String username= (String) PropertyUtils.getProperty(user,"username");
log.info("username:"+username); //输出结果:username:小李
2.2、通过反射实现
方法一:通过propertyName手动拼接的方式
public static void setValue(Object obj, String propertyName,
Object value,Class parameterTypes) throws Exception {
// 1.根据属性名称就可以获取其set方法 例如:setAge
String getMethodName = "set"
+ propertyName.substring(0, 1).toUpperCase()
+ propertyName.substring(1);
//2.获取方法对象
Class c = obj.getClass();
//根据方法名称setAge获取类中指定方法.可以带参数
Method m= c.getMethod(getMethodName,parameterTypes);
//3 通过方法的反射操作方法 相当于:User.setAge()方法
m.invoke(obj,value);
}
public static Object getValue(Object obj, String propertyName) throws Exception {
// 1.根据属性名称就可以获取其get方法 例如:getAge
String getMethodName = "get"
+ propertyName.substring(0, 1).toUpperCase()
+ propertyName.substring(1);
//2.获取方法对象
Class c = obj.getClass();
//get方法都是public的且无参数
//根据方法名称getAge获取类中指定方法.可以带参数
Method m= c.getMethod(getMethodName);
//3 通过方法的反射操作方法 相当于:User.getAge()方法
Object value = m.invoke(obj);
return value;
}
测试结果:
try {
User user=new User();
setValue(user,"username","小明",String.class);
String username = (String) getValue(user,"username");
log.info("username:"+username); //输出结果:username:小明
} catch (Exception e) {
e.printStackTrace();
}
方法二:通过PropertyDescriptor反射调用类属性的set和get方法
/**
* 功能描述:根据对象的属性名获取其属性值
* //方法二:通过PropertyDescriptor反射调用类属性的set和get方法
* @MethodName: getValueByPropertyName
* @MethodParam: [obj, propertyName]
* @Return: java.lang.Object
* @Author: yyalin
* @CreateDate: 2022/4/26 16:13
*/
public static Object getValueByPropertyName(Object obj, String propertyName) {
try {
Class c = obj.getClass(); //获取类对象
//属性描述器
PropertyDescriptor propertyDes = new PropertyDescriptor(propertyName, c);
//获得用于写入属性值的方法Method getWriteMethod()
Method getMethod = propertyDes.getReadMethod(); //获得用于读取属性值的get方法
Object value = getMethod.invoke(obj); //对象.get方法 相当于:User.getAge()方法
return value;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}