您的位置:首页 > 编程语言 > Java开发

Map与JavaBean互转原理(内省机制)

2016-08-25 10:50 288 查看

1.javabean 转 map

定义一个Person的javabean

public class Person {

private String name;
private int age;

public Person() {
super();
}

public Person(String name,int age){
this.name=name;
this.age=age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}

}


解说:

定义一个Person的javabean是用来下面演示demo使用


将map集合转javabean

/**
* javabean转成map
* @param obj
* @return
* @throws Exception
*/
public static Map<String,Object> bean2Map(Object obj) throws Exception{
Map<String, Object> map =new HashMap<>();
// 获取person类的BeanInfo对象
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
//获取属性描述器
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {

//获取属性名
String key = propertyDescriptor.getName();
if(key.equals("class"))
continue;
//获取该属性的值
Method readMethod = propertyDescriptor.getReadMethod();
////通过反射来调用Person的定义的getName()方法
Object value = readMethod.invoke(obj);
map.put(key, value);
}
return map;
}

/**
* 打印map集合
* @param map
*/
private static void printMap(Map<String, Object> map) {
for (Entry<String, Object> m : map.entrySet()) {
System.out.println(m.getKey()+"="+m.getValue());
}
System.out.println("---------------------------------");
}

-------------------------------
执行main方法:
public static void main(String[] args) throws Exception {
Person per=new Person("liujun",12);
Map<String, Object> bean2Map = bean2Map(per);
printMap(bean2Map);
}

----------------------
输出的结果:
name=liujun
age=12
---------------------------------


解说:

1.Introspector 类:获取person类的BeanInfo对象

2.BeanInfo 类:person类的BeanInfo对象

3.PropertyDescriptor 类:person类的属性描述器

2.map 转 javabean

/**
* map集合转javabean
* @param map
* @param clz
* @return
* @throws Exception
*/

public static <T>T map2Bean(Map<String,Object> map , Class<T> clz) throws Exception{
//new 出一个对象
T obj=clz.newInstance();
// 获取person类的BeanInfo对象
BeanInfo beanInfo = Introspector.getBeanInfo(clz);
//获取属性描述器
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
//获取属性名
String key = propertyDescriptor.getName();
Object value=map.get(key);
if(key.equals("class"))
continue;
Method writeMethod = propertyDescriptor.getWriteMethod();
//通过反射来调用Person的定义的setName()方法
writeMethod.invoke(obj,value);
}
return obj;
}

-------------------------------
执行main方法:
public static void main(String[] args) throws Exception {
Person per=new Person("liujun",12);
Map<String, Object> bean2Map = bean2Map(per);
printMap(bean2Map);
Person map2Bean = map2Bean(bean2Map, Person.class);
System.out.println(map2Bean.toString());
}

-----------------------------
输出的结果:
name=liujun
age=12
---------------------------------
Person [name=liujun, age=12]


3.转换的原理(内省机制)

什么是内省机制?

内省机制是获取JavaBean的成员(事件,方法,属性),设置/获取属性值

内省机制与反射有什么区别?

反射是获取类的字节码对象,通过字节码对象创建类的对象,调用相关方法

内省机制的核心类:

Introspector

Introspector类为访问目标Jave Bean支持的属性、事件和方法提供了标准方法。对于属性、事件和方法中的每一类信息,Introspector会分别分析目标bean以及其父类,寻找显式或隐式信息并用其构建一个能够全面描述目标bean的BeanInfo对象。过调用Introspector.getBeanInfo()方法来获得指定类的bean信息


BeanInfo

BeanInfo类是为了获取对bean属性的控制权。只需提供属性名和所属的bean类,就可以为每个属性构建一个PropertyDescriptor


PropertyDescriptor

PropertyDescriptor是属性描述器,通过PropertyDescriptor可以获取javabean中的定义的属性、事件和方法。


内省机制代码的分析:

public static void main(String[] args) throws Exception {
//通过Introspector获取person类的BeanInfo对象
BeanInfo beanInfo = Introspector.getBeanInfo(Person.class);
//通过beanInfo对象获取属性描述器propertyDescriptors
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
//遍历每一个属性描述器PropertyDescriptors
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
System.out.println("-------------");
//获取某个属性的名称:例如:Person的定义的name属性名
System.out.println(propertyDescriptor.getName());
//获取某个属性的类型:例如:Person的定义的name属性的类型是class java.lang.String
System.out.println(propertyDescriptor.getPropertyType());
//获取某个属性的getxxx()方法,例如:Person的定义的getName()方法
Method readMethod = propertyDescriptor.getReadMethod();
//获取某个属性的setxxx()方法,例如:Person的定义的setName()方法
Method writeMethod = propertyDescriptor.getWriteMethod();
System.out.println(readMethod);
System.out.println(writeMethod);
}
}

-------------------------------

输出的结果:

-------------
age
int
public int xmg.day24.neisheng.Person.getAge()
public void xmg.day24.neisheng.Person.setAge(int)
-------------
class
class java.lang.Class
public final native java.lang.Class java.lang.Object.getClass()
null
-------------
name
class java.lang.String
public java.lang.String xmg.day24.neisheng.Person.getName()
public void xmg.day24.neisheng.Person.setName(java.lang.String)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息