【问题标题】:Object in Object to HashMap with reflection对象中的对象到带有反射的 HashMap
【发布时间】:2019-05-20 17:57:41
【问题描述】:

项目:

我目前正在使用一个名为Netuno的工具来开发一个api,所以要将对象导出为json,需要将对象转换为HashMap,为此在父类中开发了一个方法导出对象。

方法:
   public Map<String, Object> export() {
        Object obj = this;
        Map<String, Object> map = new HashMap<>();
        for (Field field : obj.getClass().getDeclaredFields()) {
            field.setAccessible(true);
            try {
                map.put(field.getName(), field.get(obj));
            } catch (Exception e) {
                //todo e
            }
        }
        return map;
    }

这有效,但仅适用于简单对象。

我的问题:

如果对象在我的方法中包含复杂对象,它也无法将它们导出到 HashMap。

示例结构:

public abstract class Master {
 public Map < String, Object >
  export () {
   Object obj = this;
   Map < String, Object > map = new HashMap < > ();
   for (Field field: obj.getClass().getDeclaredFields()) {
    field.setAccessible(true);
    try {
     map.put(field.getName(), field.get(obj));
    } catch (Exception e) {
     //todo e
    }
   }
   return map;
  }
}

public class Foo extends Master {
 private int a;
 private int b;
 private String c;
 private Bar bar;
//...
}

public class Bar extends Master {
 private int q;
 private int w;
 private String e;
//...
}

我是这样用的:

return new Bar(/*data*/).export();

输出:

{
  "a": 2,
  "b": 5,
  "c": "abc",
  "bar": "myproject.myPackage.Bar@XXXXX"
}

预期输出:

{
  "a": 2,
  "b": 5,
  "c": "abc",
  "bar": {
    "q": 10,
    "w": 15,
    "e": "it works"
  }
}

【问题讨论】:

  • 有些库也可以为您提供您想要的结果(将对象序列化为 JSON/将 JSON 反序列化为对象),例如 Gson/Jackson/更多,也许需要研究一下?跨度>
  • 如果 field.get(obj) 是 Master cast to master 的实例,您可以添加一个条件并放入地图导出方法结果,但正如 Mark 提到的,有一些库具有该功能
  • @Mark 感谢这些库 :),但我试图不使用它们来不破坏我的框架标准

标签: java oop reflection hashmap hierarchy


【解决方案1】:

你需要决定一个值是我应该放在地图中还是递归地。因此,您可以使用这样的简单方法:

private boolean isSimpleType(Class<?> type) {
    return type.isPrimitive() ||
            Boolean.class == type ||
            Character.class == type ||
            CharSequence.class.isAssignableFrom(type) ||
            Number.class.isAssignableFrom(type) ||
            Enum.class.isAssignableFrom(type);
}

此方法为所有原始类型或 Wrapper 对象、字符串和枚举返回 true。您可以简单地调整这些方法以满足您的需求。查看here 了解有关如何确定一个类是否简单的更多详细信息。

现在你可以用它来转换一个对象:

public Map<String, Object> convert(Object object) {
    Map<String, Object> map = new HashMap<>();
    for (Field field : object.getClass().getDeclaredFields()) {
        field.setAccessible(true);
        try {
            if (isSimpleType(field.getType())) {
                map.put(field.getName(), field.get(object));
            } else {
                map.put(field.getName(), convert(field.get(object)));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return map;
}

您也可以调整它以执行您的 export 方法。

你的例子的结果是这样的:

{a=2, b=5, bar={q=10, e=it works, w=15}, c=abc}

除此之外,我强烈建议使用一个库(如Jackson),它已经完美地完成了这样的事情。这是使用 Jackson 的相同解决方案:

Map result = new ObjectMapper().convertValue(object, Map.class);

或者如果您需要类型安全:

ObjectMapper mapper = new ObjectMapper();
MapType mapType = mapper.getTypeFactory().constructMapType(Map.class, String.class, Object.class);
Map<String, Object> result = mapper.convertValue(value, mapType);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    • 2017-09-16
    • 2018-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多