zoukankan      html  css  js  c++  java
  • JavaBean和Map的相互转换

    JavaBean和Map的相互转换

    一、JavaBean

    1.什么是JavaBean?

    JavaBean其实就是一种遵循特定写法的类,必须遵循一定的规范:

    • 类必须由public修饰,并且保证有公共的无参数的构造器
    • 包含操作属性的的public方法,getter setter方法
    • 字段是私有的

    一个JavaBean是由3部分组成,分别是属性、方法、和事件。注意这里的属性是property,表示的是状态,并不是字段(Field)我们在刚开始学面向对象的时候其实有的时候也是用到了这个规范,我们写的getter和setter方法,比如public void setName(String name){ this.name = name;}属性其实就是name,在比如public int getAge(){return 19;},属性其实就是age。一般的,我们写getter个setter方法用的是IDE自己生成的,属性和字段同名。一定要区分属性和字段,它们并不是一个东西,也存在属性名和字段名不同。

    2.内省机制

    内省机制的作用就是用来查看和操作JavaBean的属性。

    • 获取JavaBean的属性名
    • 通过getter方法给属性获取值,通过setter给属性设置值

    常用的API

    Introspector类中

    static BeanInfo getBeanInfo(Class<?> beanClass) 
    在 Java Bean 上进行内省,了解其所有属性、公开的方法和事件。 
    static BeanInfo getBeanInfo(Class<?> beanClass, Class<?> stopClass) 
    在给定的“断”点之下,在 Java Bean 上进行内省,了解其所有属性和公开的方法。 
    

    可以看到在Introspector类中有两个静态方法可以获得获取JavaBean的信息,一般的第一个会得到父类Object.class中的getClass方法,第二种会屏蔽掉Object类中的方法。返回一个BeanInfo,在BeanInfo接口中有一个方法可以获得bean的描述器对象

     MethodDescriptor[] getMethodDescriptors() 获得 beans MethodDescriptor。 
     PropertyDescriptor[] getPropertyDescriptors()  获得 beans PropertyDescriptor。 
    

    分别返回的是各自的描述器对象

     Method getReadMethod()  获得应该用于读取属性值的方法。 就是getter方法
     Method getWriteMethod()  获得应该用于写入属性值的方法。 就是setter方法
    
    public class User {
    	private String name;
    	private int age;
    	private boolean man;
    	public String getName() {
    		return name;
    	}
    	...省略剩余getter setter方法
    	@Override
    	public String toString() {
    		return "User [name=" + name + ", age=" + age + ", man=" + man + "]";
    	}
    	public static void main(String[] args) throws Exception {
            //获得JavaBean的描述信息
    		BeanInfo info = Introspector.getBeanInfo(User.class,Object.class);
            //获取JavaBean的属性描述器对象,返回的是一个描述器数组
    		PropertyDescriptor[] pds = info.getPropertyDescriptors();
            //利用反射创建这个类的对象,当然这只是测试一下
    		User u = User.class.newInstance();
           	//对描述器对象进行迭代
    		for (PropertyDescriptor pd : pds) {
    			//获取属性名称 和属性的类型
    			System.out.println(pd.getName()+","+pd.getPropertyType()());
                 //获取getset方法
    			Method get = pd.getReadMethod();
    			Method set = pd.getWriteMethod();
    			System.out.println("getter方法:"+get);
    			System.out.println("setter方法:"+set);
    			
    			//用反射给name属性设置值
    			if("name".equals(pd.getName())){
    				Method setter = pd.getWriteMethod();
    				setter.invoke(u, "xx");
    				Method getter = pd.getReadMethod();
    				Object o = getter.invoke(u);//获取名字
    				System.out.println(o);
    			}
    		}
    		System.out.println(u);
    	}
    }
    

    二、JavaBean和Map的相互转化

    我们可以发现javabean和map之间有很多相似之处.在map中是一对键值对key-value,而在JavaBean中是属性名-属性值。现在对这两种进行相互转换

    1.JavaBean转化为Map

    思路:把bean转化为map,不过就是把bean中的属性名给map的key,把属性值给map中的value。在程序上表达,提供一个方法,传入的是一个JavaBean对象,返回的是一个Map。

    上代码:

    //把JavaBean转化为map
    public static Map<String,Object> bean2map(Object bean) throws Exception{
        Map<String,Object> map = new HashMap<>();
        //获取JavaBean的描述器
        BeanInfo b = Introspector.getBeanInfo(bean.getClass(),Object.class);
        //获取属性描述器
        PropertyDescriptor[] pds = b.getPropertyDescriptors();
        //对属性迭代
        for (PropertyDescriptor pd : pds) {
            //属性名称
            String propertyName = pd.getName();
            //属性值,用getter方法获取
            Method m = pd.getReadMethod();
            Object properValue = m.invoke(bean);//用对象执行getter方法获得属性值
    
            //把属性名-属性值 存到Map中
            map.put(propertyName, properValue);
        }
        return map;
    }
    

    2.把Map转化为JavaBean

    思路:map转化为javabean,不就是把map的value设置给属性为属性值,也就在找到bean中和Map中key相同的属性名,把这个key对应的value设置给这个属性。在程序上表达就是,提供一个方法,传入map对象和一个bean的Class类型,返回一个JavaBean对象。注意,这里传入的参数多了一个,因为肯定得用反射创建bean对象把,如果只传入一个map对象,怎么创建对象?怎么知道吧map转化为什么类型的JavaBean。好了,直接撸代码:

    //把Map转化为JavaBean
    public static <T> T map2bean(Map<String,Object> map,Class<T> clz) throws Exception{
        //创建一个需要转换为的类型的对象
        T obj = clz.newInstance();
        //从Map中获取和属性名称一样的值,把值设置给对象(setter方法)
    
        //得到属性的描述器
        BeanInfo b = Introspector.getBeanInfo(clz,Object.class);
        PropertyDescriptor[] pds = b.getPropertyDescriptors();
        for (PropertyDescriptor pd : pds) {
            //得到属性的setter方法
            Method setter = pd.getWriteMethod();
            //得到key名字和属性名字相同的value设置给属性
            setter.invoke(obj, map.get(pd.getName()));
        }
        return obj;
    }
    
  • 相关阅读:
    springboot项目在IDEA根据不同的开发人员读取不同的配置文件
    Idea中一个服务按多个端口同时启动
    修改feign解析器替换json
    Intellij IDEA中启动多个微服务--开启Run Dashboard管理
    解决springboot乱码和window cmd乱码
    调用远程linux服务器shell脚本
    cp复制命令详解
    ftp列出具体目录的所有目录,和目录按照文件类型列出
    Linux下Redis开机自启(Centos)
    vsftpd 配置上传失败553
  • 原文地址:https://www.cnblogs.com/tfper/p/9931656.html
Copyright © 2011-2022 走看看