一、传统属性赋值弊端
class Emp {
private String ename ;
private String job ;
// setter、getter略
}
public class JavaReflectDemo {
public static void main(String[] args) throws Exception {
Emp emp = new Emp() ; // 实例化对象
emp.setEname("SMITH"); // 属性设置
emp.setJob("CLERK"); // 属性设置
System.out.println("姓名:" + emp.getEname() + "、职位:" + emp.getJob());
}
}
二、属性自动赋值实现思路
定义一个ClassInstanceFactory类负责所有的反射处理
public class ClassInstanceFactory {
//实例化对象的创建方法,该对象可以根据传入的字符串结构 “属性:内容|属性:内容|...”
public static <T> T create(Class<?> clazz,String value) {
return null;
}
}
class JavaReflectDemo454{
public static void main(String[] args) {
String value="name:xiaohei|age:5";
Dog dog=ClassInstanceFactory.create(Dog.class, value);
System.out.println("姓名:"+dog.getName()+"年龄:"+dog.getAge());
}
}
三、单级属性赋值
单级属性赋值是指简单java类之间没有任何的引用联系,这类操作只需要通过反射实例化对象,并根据属性找到相应的setter()方法,反射进行方法调用为属性赋值即可。
1、由于需要通过属性找到set方法,所以需要提供一个首字母大写的功能,为此定义一个字符串工具类。
package com.lxh.seventeenchapter;
public class StringUtils {
/*
* 实现字符串首字母大写,如果只有一个字母则直接将此字母大写
* @param str要转换的字符串
* @return 大写处理结果,如果传入的字符串为空则返回null
*/
public static String initcap(String str) {
if(str==null||"".equals(str)) {
return str;
}
if(str.length()==1){ //判断字符串长度
return str.toUpperCase(); //单个字母直接大写
}else { //首字母大写
return str.substring(0,1).toUpperCase()+str.substring(1);
}
}
}
2、定义BeanUtils工具类,通过该类实现setter方法的调用并进行属性赋值(String为例)
package com.lxh.seventeenchapter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class BeanUtils {
/*
* 实现指定对象的属性设置
* @param obj要进行反射操作的数理化对象
* @param value 包含指定内容的字符串,格式"属性:内容|属性:内容"
*
*/
public static void setValue(Object obj,String value) {
String results[]=value.split("\\|");//按照“|”对每一组属性进行拆分
for (int i = 0; i < results.length; i++) {
//attval[0]保存的属性名称,attval[1]保存属性内容
String attval[]=results[i].split(":");
try {
Field field=obj.getClass().getDeclaredField(attval[0]);//获取成员
//根据成员名称拼出要使用的set方法,同时根据Field获取属性类型
Method setMethod=obj.getClass().getDeclaredMethod("set"+StringUtils.initcap(attval[0],field.getType()));
setMethod.invoke(obj, attval[1]);
} catch (NoSuchFieldException | SecurityException e) {
e.printStackTrace();
}
}
}
}
3、ClassInstanceFactory负责调用BeanUtils类实现属性内容的赋值
public class ClassInstanceFactory {
//实例化对象的创建方法,该对象可以根据传入的字符串结构 “属性:内容|属性:内容|...”
public static <T> T create(Class<?> clazz,String value) {
//如果想要采用反射进行简单java类对象属性设置的时候,类中必须有无参构造
try {
Object obj=clazz.getDeclaredConstructor().newInstance();
BeanUtils.setValue(obj, value);
return (T)obj; //返回对象
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
}
本文介绍如何利用Java反射机制解决传统属性赋值的弊端,实现属性的自动赋值。通过自定义ClassInstanceFactory类和BeanUtils工具类,演示了如何根据传入的字符串结构动态创建对象并设置其属性值。
160

被折叠的 条评论
为什么被折叠?



