JAVA的反射機制主要作用是用來訪問對象的屬性、方法等等。所以,JAVA中對象和Map相互轉換可以利用JAVA的反射機制來實現。例子如下:
一、對象轉Map的方法
1 public static Map<String, Object> javaBean2Map(Object javaBean) throws Exception { 2 Map<String, Object> map = new HashMap<>(); 3 Method[] methods = javaBean.getClass().getMethods(); // 獲取所有方法 4 for (Method method : methods) { 5 if (method.getName().startsWith("get")) { 6 String field = method.getName(); // 拼接屬性名 7 field = field.substring(field.indexOf("get") + 3); 8 field = field.toLowerCase().charAt(0) + field.substring(1); 9 Object value = method.invoke(javaBean, (Object[]) null); // 執行方法 10 map.put(field, value); 11 } 12 } 13 return map; 14 }
本例中,使用了getMethods()方法,支持獲取對象父類的私有屬性。這里也可以使用getDeclaredMethods()方法來代替getMethods()方法。兩者有一定的區別,具體要根據需轉換對象的情況:
getMethods():獲取當前類及所有繼承的、父類的public修飾的方法,僅包括public。
getDeclaredMethods():獲取當前類的所有方法,包括public/private/protected/default修飾的方法。
同理,這個區別也適用於獲取類屬性的getFields()和getDeclaredFields()、獲取類構造方法的getConstructors()和getDeclaredConstructors()。
二、Map轉對象的方法
1 public static Object map2JavaBean(Class<?> clazz, Map<String, Object> map) throws Exception { 2 Object javabean = clazz.newInstance(); // 構建對象 3 Method[] methods = clazz.getMethods(); // 獲取所有方法 4 for (Method method : methods) { 5 if (method.getName().startsWith("set")) { 6 String field = method.getName(); // 截取屬性名 7 field = field.substring(field.indexOf("set") + 3); 8 field = field.toLowerCase().charAt(0) + field.substring(1); 9 if (map.containsKey(field)) { 10 method.invoke(javabean, map.get(field)); 11 } 12 } 13 } 14 return javabean; 15 }
本例中,同樣是通過獲取對象的所有方法進行循環,然后執行類屬性的set方法將值存進對象的屬性中。因為上面提到了,反射的方法都是有關鍵字范圍的,而通常類屬性的get()、set()都是public的,類屬性本身則可能是private的,所以這樣做會更加通用,如果沒有繼承關系或者類屬性都是public的,那么通過迭代map取出值,用field.set(obj, value)方法會更簡便一點。
