我有一大堆 java 对象,它们都继承自一个共享对象,每个都包含许多字段成员(属性)。但是,并非所有对象上的所有字段都保证被初始化。还有一些包含在超类中的字段也应该包含在内。我希望创建一个包含所有已初始化成员的映射,其中成员的标识符作为键及其值和映射值。
这甚至可能吗?我简要地研究了看起来很有希望的反射,但我没有太多经验。所有值都是原始值类型,必要时可以存储在字符串中。
我有一大堆 java 对象,它们都继承自一个共享对象,每个都包含许多字段成员(属性)。但是,并非所有对象上的所有字段都保证被初始化。还有一些包含在超类中的字段也应该包含在内。我希望创建一个包含所有已初始化成员的映射,其中成员的标识符作为键及其值和映射值。
这甚至可能吗?我简要地研究了看起来很有希望的反射,但我没有太多经验。所有值都是原始值类型,必要时可以存储在字符串中。
结合我找到的答案:
public static Map<String, String> generatePropertiesMap(Object o)
{
Map<String, String> properties = new HashMap<String, String>();
for (Field field : getAllDeclaredFields(o)) {
Boolean acessibleState = field.isAccessible();
field.setAccessible(true);
Object value;
try {
value = field.get(o);
if (value != null) {
properties.put(field.getName(), value.toString());
}
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
}
field.setAccessible(acessibleState);
}
return properties;
}
private static List<Field> getAllDeclaredFields(Object o) {
List<Field> list = new ArrayList<Field>();
List<Field[]> fields = new ArrayList<Field[]>();
//work up from this class until Object
Class next = o.getClass();
while (true) {
Field[] f = next.getDeclaredFields();
fields.add(f);
next = next.getSuperclass();
if (next.equals(Object.class))
break;
}
for (Field[] f : fields) {
list.addAll(Arrays.asList(f));
}
return list;
}
用这个
public void method method(Object obj) {
Map initializedFieldsMap = new HashMap();
for (Field field : obj.getClass().getDeclaredFields()) {
Boolean acessibleState = field.isAccessible();
field.setAccessible(true);
Object value;
try {
value = field.get(obj);
if (value != null) {
initializedFieldsMap.put(field.getName(), new WeakReference(value));
}
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
}
field.setAccessible(acessibleState);
}
return initializedFieldsMap;
}
它在这里使用了WeakReference,因此对象值不会被“卡住”(但它仍然不理想)并且不适合 GC,以从 Map 使用中访问值(例如字符串):
String xxx = (String)map.get("value").get();