本篇内容主要讲解“Java BeanMap如何实现Bean与Map的相互转换”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java BeanMap如何实现Bean与Map的相互转换”吧!
@Data public class Student { private int id; private String name; private Integer age; }
Student student = new Student(); BeanMap beanMap = BeanMap.create(student);
此时的beanMap就是一个map类型
但是对于直接生成的beanMap无法添加key,也无法删除key(会报错),并且修改值会直接影响到student这个对象。
如果有这个需求可以再进一步转换为HashMap(如果没这个需要,就不要再转换,避免不必要的性能浪费)
HashMap map = new HashMap(); map.putAll(beanMap);
普通Map转转换成bean
HashMap map = new HashMap(); map.put("name","hello world"); Student student = new Student(); BeanMap beanMap = BeanMap.create(student); beanMap.putAll(map);
利用了修改beanMap会影响bean的特性,将map put到beanMap完成转换.
beanMap转成对应的bean
public static <T> T beanMapToBean(BeanMap beanMap) { if (beanMap == null) { throw new DataStreamException("bean.can.not.be.null"); } return (T) beanMap.getBean(); }
直接调用getBean方法就可以获取beanMap对应的bean
先看beanMap
public abstract class BeanMap implements Map
继承自Map接口,实现了contains,remove,put,get等操作
public Object remove(Object key) { throw new UnsupportedOperationException(); }
但是remove会抛出UnsupportedOperationException
BeanMap.create()方法通过asm动态生成字节码创建一个beanMap
那么我们来看看创建出来的beanMap的字节码文件
import java.math.BigDecimal; import java.util.Date; import java.util.Set; import net.sf.cglib.beans.BeanMap; import net.sf.cglib.beans.FixedKeySet; public class Student$$BeanMapByCGLIB$$54bf0fe9 extends BeanMap { private static FixedKeySet keys; private static final Class CGLIB$load_class$java$2Eutil$2ESet; private static final Class CGLIB$load_class$java$2Elang$2EInteger; private static final Class CGLIB$load_class$java$2Elang$2EString; private static final Class CGLIB$load_class$java$2Emath$2EBigDecimal; private static final Class CGLIB$load_class$java$2Eutil$2EDate; public Student$$BeanMapByCGLIB$$54bf0fe9() { } public BeanMap newInstance(Object var1) { return new Student$$BeanMapByCGLIB$$54bf0fe9(var1); } public Student$$BeanMapByCGLIB$$54bf0fe9(Object var1) { super(var1); } public Object get(Object var1, Object var2) { Student var10000 = (Student)var1; String var10001 = (String)var2; switch(((String)var2).hashCode()) { case -600094315: if (var10001.equals("friends")) { return var10000.getFriends(); } break; case 3355: if (var10001.equals("id")) { return new Integer(var10000.getId()); } break; case 96511: if (var10001.equals("age")) { return var10000.getAge(); } break; case 3373707: if (var10001.equals("name")) { return var10000.getName(); } break; case 104079552: if (var10001.equals("money")) { return var10000.getMoney(); } break; case 1069376125: if (var10001.equals("birthday")) { return var10000.getBirthday(); } } return null; } public Object put(Object var1, Object var2, Object var3) { Student var10000 = (Student)var1; String var10001 = (String)var2; switch(((String)var2).hashCode()) { case -600094315: if (var10001.equals("friends")) { Set var7 = var10000.getFriends(); var10000.setFriends((Set)var3); return var7; } break; case 3355: if (var10001.equals("id")) { Integer var10003 = new Integer(var10000.getId()); var10000.setId(((Number)var3).intValue()); return var10003; } break; case 96511: if (var10001.equals("age")) { Integer var6 = var10000.getAge(); var10000.setAge((Integer)var3); return var6; } break; case 3373707: if (var10001.equals("name")) { String var5 = var10000.getName(); var10000.setName((String)var3); return var5; } break; case 104079552: if (var10001.equals("money")) { BigDecimal var4 = var10000.getMoney(); var10000.setMoney((BigDecimal)var3); return var4; } break; case 1069376125: if (var10001.equals("birthday")) { Date var10002 = var10000.getBirthday(); var10000.setBirthday((Date)var3); return var10002; } } return null; } static { CGLIB$STATICHOOK1(); keys = new FixedKeySet(new String[]{"birthday", "money", "name", "id", "age", "friends"}); } static void CGLIB$STATICHOOK1() { CGLIB$load_class$java$2Eutil$2ESet = Class.forName("java.util.Set"); CGLIB$load_class$java$2Elang$2EInteger = Class.forName("java.lang.Integer"); CGLIB$load_class$java$2Elang$2EString = Class.forName("java.lang.String"); CGLIB$load_class$java$2Emath$2EBigDecimal = Class.forName("java.math.BigDecimal"); CGLIB$load_class$java$2Eutil$2EDate = Class.forName("java.util.Date"); } public Set keySet() { return keys; } public Class getPropertyType(String var1) { switch(var1.hashCode()) { case -600094315: if (var1.equals("friends")) { return CGLIB$load_class$java$2Eutil$2ESet; } break; case 3355: if (var1.equals("id")) { return Integer.TYPE; } break; case 96511: if (var1.equals("age")) { return CGLIB$load_class$java$2Elang$2EInteger; } break; case 3373707: if (var1.equals("name")) { return CGLIB$load_class$java$2Elang$2EString; } break; case 104079552: if (var1.equals("money")) { return CGLIB$load_class$java$2Emath$2EBigDecimal; } break; case 1069376125: if (var1.equals("birthday")) { return CGLIB$load_class$java$2Eutil$2EDate; } } return null; } }
这个生成的类继承自BeanMap,在构造时传进来bean实例,并且根据bean的属性创建对应的get/put方法
可以看出来在执行get和put时都是根据属性名称找到对应bean实例的set/get方法进行处理。也因此beanMap和对应实例会相互影响
还具备getPropertyType获取字段类型的功能
在bean转map过程中除了生成这个动态class之外(生成之后会缓存,对于同一类型的bean,不会重复创建),整个过程没有真正复制对象变成map(避免的内存的浪费),也没有通过效率较慢的反射去操作bean实例。因此BeanMap性能是比较不错的。
到此,相信大家对“Java BeanMap如何实现Bean与Map的相互转换”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。