通过java反射给对象赋值
项目背景:
需要对一个JSONArray对象数组进行解析,并把数据解析填充进实体中。由于字段太多,不愿通过if else的方式判断来赋值。遂想到通过反射的方式来实现功能
入参demo如下:
"data": [ { "column": "age", "result": "20", }, { "column": "height", "result": "181", }, { "column": "weight", "result": "140", } //还有很多其他的字段,类型均相同 ]
相应的实体类demo
public class Student { private Integer age; private Integer height; private Integer weight; }
解决方案:
1、先将jsonarray数据通过遍历解析到map中 2、通过反射获取字段数组,遍历获取字段名,通过map获取相应结果 注意: 需要实体类中字段属性和jsonarray中做到相同
代码如下:
public Student handleObject(JSONArray jsonArray) { Map<String, Object> map = jsonArray2Map(jsonArray); Student student = convent(Student.class, map); return student; } /** * json数组转换成相应map * * @param jsonArray * @return */ private Map<String, Object> jsonArray2Map(JSONArray jsonArray) { Map<String, Object> map = new HashMap<>(); for (int i = 0; i < jsonArray.size(); i++) { JSONObject item = jsonArray.getJSONObject(i); String key = item.getString("column"); map.put(key, Integer.valueOf(item.getString("result"))); } return map; } /** * 给实体赋值,由于不止一个需要这样,所以做成泛型的方式 * @param clazz * @param map * @param <T> * @return */ private <T> T convent(Class<T> clazz, Map<String, Object> map) { T t = null; try { t = clazz.newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } Field[] fields = clazz.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { Field field = fields[i]; //跳过访问控制 field.setAccessible(true); try { if (map.containsKey(field.getName())) { field.set(t, map.get(field.getName())); } } catch (IllegalAccessException e) { System.out.println("属性注入失败:" + e); } } return t; }
后记
该方法只适合对类型一致的数据,数据类型的不一致时,还在考虑中。后续再更新