您好,登錄后才能下訂單哦!
本篇內容主要講解“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進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。