Java内省:要映射的对象

Rad*_*dim 38 java introspection

我有一个Java对象obj具有属性obj.attr1,obj.attr2等属性通过额外的间接水平可能访问:obj.getAttr1(),obj.getAttr2(),如果不公开.

挑战:我想一个函数,一个对象,并返回一个Map<String, Object>,其中的键是字符串"attr1","attr2"等等和值对应的对象obj.attr1,obj.attr2.我想这个函数会被调用

  • toMap(obj),
  • toMap(obj, "attr1", "attr3")(其中attr1attr3obj属性的子集),
  • 或者toMap(obj, "getAttr1", "getAttr3")如果有必要的话.

我对Java的内省了解不多:你是如何用Java做的?

现在,我toMap()对每个我关心的对象类型都有一个专门的实现,而且它太多样板了.


注意:对于那些了解Python的人,我想要类似的东西obj.__dict__.或者dict((attr, obj.__getattribute__(attr)) for attr in attr_list)对于子集变体.

End*_*ios 49

用户的另一种方式JacksonObjectMapperconvertValueex:

 ObjectMapper m = new ObjectMapper();
 Map<String,Object> mappedObject = m.convertValue(myObject,Map.class);
Run Code Online (Sandbox Code Playgroud)

  • 我在此解决方案中遇到的问题是,它以递归方式转换对象,可能破坏更深层对象组合中的类型(例如,第3层中的Date实例将转换为Long,因为这是ObjectMapper的默认设置)。由于我需要用于数据规范化的方法,因此这是一个问题... (2认同)

And*_*rey 46

使用Apache Commons BeanUtils:http://commons.apache.org/beanutils/.

Map for JavaBeans的一个实现,它使用内省来获取和放置bean中的属性:

Map<Object, Object> introspected = new org.apache.commons.beanutils.BeanMap(object); 
Run Code Online (Sandbox Code Playgroud)

注意:尽管API返回Map<Object, Object>(从1.9.0开始),返回映射中键的实际类是java.lang.String

  • +1好的,这个正式是最少量的代码. (3认同)

Chr*_*ung 27

您可以使用JavaBeans内省.阅读java.beans.Introspector课程:

public static Map<String, Object> introspect(Object obj) throws Exception {
    Map<String, Object> result = new HashMap<String, Object>();
    BeanInfo info = Introspector.getBeanInfo(obj.getClass());
    for (PropertyDescriptor pd : info.getPropertyDescriptors()) {
        Method reader = pd.getReadMethod();
        if (reader != null)
            result.put(pd.getName(), reader.invoke(obj));
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

大警告:我的代码只处理getter方法; 它找不到裸露的田野.对于字段,请参阅高度咖啡因的答案.:-)(你可能想要结合这两种方法.)


hig*_*ted 15

这是一个粗略的近似值,希望足以让你指向正确的方向:

public Map<String, Object> getMap(Object o) {
    Map<String, Object> result = new HashMap<String, Object>();
    Field[] declaredFields = o.getClass().getDeclaredFields();
    for (Field field : declaredFields) {
        result.put(field.getName(), field.get(o));
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

  • +1我认为在你的解决方案和我的解决方案之间,OP应该让它解决.(你的只处理字段;我只处理getter方法.:-P) (3认同)

Ami*_*far 5

这是一个非常简单的方法.

使用Jackson JSON lib将对象转换为JSON.

然后阅读JSON并将其转换为Map.

地图将包含您想要的一切.

这是4班轮

ObjectMapper om = new ObjectMapper();
StringWriter sw = new StringWriter();
om.writeValue(object, sw);
Map<String, Object> map = om.readValue(sw.toString(), Map.class);
Run Code Online (Sandbox Code Playgroud)

当然,额外的胜利是这是递归的,并且如果需要,将创建地图的地图