我有一个初始化的对象:
Object obj = new Object(){
final String type = "java.lang.Integer";
final Object value = 6;
};
我想将此对象重新创建为:
Integer i = 6;
有什么方法可以获取type
对象的obj
字段并使用反射创建一个新实例并将其中的值提供给它?
编辑:在扩展这个问题后,我发现如果我将对象存储在文件中并使用Jackson从文件中检索它:
Reader reader = new Reader();
MyClass[] instances = reader.readValue(fileName);
MyClass
定义为:
class MyClass{
List<Object> fields;
.
.
.
}
现在我正在迭代fields
并使用代码将它们转换为适当的对象:
public static Class<?> getTypeForObject(Object field) {
Field returnType = null;
try {
returnType = field.getClass().getDeclaredField("type");
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
return returnType.getType();
}
public static Object getValueForObject(Object field) {
Object obj = null;
try {
obj = field.getClass().getDeclaredField("value").get(field);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
return obj;
}
但是当我看到field.getClass()
这个词时,它会给我LinkedHashMap
作为它的类。我很困惑为什么如果它被内部视为Map
,如果我想用反射做而不使用具体的数据结构,那么我将剩下哪些选项,以便一切都被概括。
答案 0 :(得分:8)
是的,你可以。但由于obj
的类型是一个扩展java.lang.Object
的匿名类,因此您无法直接引用其字段(type
和value
),只能通过反射。 / p>
以下是您可以执行此操作的代码:
String type = (String) obj.getClass().getDeclaredField("type").get(obj);
Object value = obj.getClass().getDeclaredField("value").get(obj);
// Type can be anything, so in order to instantiate it,
// we have to assume something. We assume it has a constructor
// which takes only a String value.
Object recreated = Class.forName(type).getConstructor(String.class)
.newInstance(value == null ? null : value.toString());
System.out.println(recreated);
答案 1 :(得分:2)
只需查看新更新的代码:
Object obj = new Object() {
final String type = "java.lang.Integer";
final Object value = 6;
};
public void demo(){
try {
Field typeField = obj.getClass().getDeclaredField("type");
typeField.setAccessible(true);
String type = typeField.get(obj).toString();
Field valueField = obj.getClass().getDeclaredField("value");
valueField.setAccessible(true);
String value = valueField.get(obj).toString();
Class intClass = Class.forName(type);
Constructor intCons = intClass.getConstructor(String.class);
Integer i = (Integer) intCons.newInstance(value.toString());
System.out.println(i);
} catch (Exception e) {
e.printStackTrace();
}
}
注意:从this问题获得帮助。
更新:现在从type
获取value
和Object obj
。
答案 2 :(得分:1)
是的,您可以使用Class.forName
。
例如,考虑一个人 -
而不是整数public static String getObjectType()
{
return "Person";
}
final String type = getObjectType();
Class.forName(type); //returns the `Person.class`, if Person.class is in classpath if not throws a `ClassNotFoundException`
要从Person.Class创建Person对象,您可以执行以下操作 -
final Person p = Person.class.getConstructor(Integer.class, String.class).newInstance(age, name);
答案 3 :(得分:1)
这将从您的对象中检索type
字段的值:obj.getClass().getDeclaredField("type").get(obj);
。