--内省机制操作javaBean
Student s = new Student("a", 12);
System.out.println(s);//内省机制Introspector类 操作javaBean的属性事件和方法
//通过Introspector.getBeanInfo()获取该javaBean的描述对象
// BeanInfo beanInfo = Introspector.getBeanInfo(Student.class);
//通过Introspector.getBeanInfo()获取该javaBean的描述对象(不包括小于等于Object的父类)
BeanInfo beanInfo = Introspector.getBeanInfo(Student.class,Object.class);
//通过beanInfo.getPropertyDescriptors()获取该javaBean的所有属性描述数组
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
//通过属性描述器来获取属性的名字 getter 和 setter 方法
String name = propertyDescriptor.getName();
System.out.println(name);
//通过属性描述器来获取属性的setter方法
Method writeMethod = propertyDescriptor.getWriteMethod();
//找到setAge方法并执行
if(writeMethod!=null&&writeMethod.getName().equals("setAge")){
writeMethod.invoke(s, 2);
System.out.println(s);
}
//通过属性描述器来获取属性的getter方法
Method readMethod = propertyDescriptor.getReadMethod();
//找到getAge方法并执行
if(writeMethod!=null&&readMethod.getName().equals("getAge")){
readMethod.invoke(s);
}
}
--通过上述方法写出一个map和javaBean的相互转换
public static void main(String[] args) throws Exception {Map<String, Object> m = new HashMap<>();
m.put("name", "小刚");
m.put("age", 3);
Student map2javaBean = map2javaBean(m, Student.class);
System.out.println(map2javaBean);
Map<String, Object> javaBean2map = javaBean2map(new Student("老王",1));
System.out.println(javaBean2map);
}
private static Map<String, Object> javaBean2map(Object obj) throws Exception {
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass(),Object.class);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
Map< String, Object> map = new HashMap<>();
//获取所有属性的名字 和 getter方法
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
String name = propertyDescriptor.getName();
Method readMethod = propertyDescriptor.getReadMethod();
Object invoke = readMethod.invoke(obj);
//把属性名和值装入map
map.put(name, invoke);
}
return map;
}
private static <T> T map2javaBean(Map<String,Object> map ,Class<T> clazz) throws Exception{
T newInstance = clazz.newInstance();
BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
//获取属性名
String name = propertyDescriptor.getName();
//如果map中存在这个属性
if(map.get(name)!=null){
Method writeMethod = propertyDescriptor.getWriteMethod();
writeMethod.invoke(newInstance, map.get(name));
}
}
return newInstance;
}
Student类代码 使用lombok封装的
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private String name;
private int age;
}
是不是非常方便 ,既然这么方便肯定已经有人帮你做好了
下面介绍下apache 的commons包,需要导入两个jar包commons-beanutils-1.9.3.jar 和 commons-logging-1.2.jar
因为commons-beanutils-1.9.3.jar 依赖于commons-beanutils-1.9.3.jar 和 commons-logging-1.2.jar
资源下载页https://download.csdn.net/download/qq_39205291/10520314
将一个map拷贝到 javaBean
Map<String, Object> m = new HashMap<>();
m.put("name", "小刚");m.put("age", 3);
Student s1 = new Student();
System.out.println(s1);
BeanUtils.copyProperties(s1, m);
System.out.println(s1);
将一个javaBean拷贝到另外一个 javaBean
Student s1 = new Student("小王",1);
Student s2 = new Student();System.out.println(s2);
//第一个参数为目标 第二个为源
BeanUtils.copyProperties(s2,s1);
System.out.println(s2);
当出现null或者""转换为integer或者Long等类型时会出现我们不想要的结果
此时可以自定义注册 指定值为null时的转换规则
ConvertUtils.register(new IntegerConverter(null), null);
String对于Date类型转换则必须指定DateConverter否则会报错(主要因为要指定Date的格式)
Map<String, Object> m = new HashMap<>();
m.put("name", "小刚");
m.put("age", null);
m.put("date","2018-01-01");
Student s1 = new Student();
DateConverter dateConverter = new DateConverter(null);
dateConverter.setPattern("yyyy-MM-dd");
ConvertUtils.register(dateConverter,Date.class);
BeanUtils.copyProperties(s1, m);
System.out.println(s1);
如果本身是Date类型则无需转换
Map<String, Object> m = new HashMap<>();
m.put("name", "小刚");
m.put("age", null);
m.put("date",new Date());
Student s1 = new Student();
BeanUtils.copyProperties(s1, m);
System.out.println(s1);