使用反射检索对象的数据类型

时间:2014-07-10 07:29:10

标签: java reflection

我有一个初始化的对象:

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,如果我想用反射做而不使用具体的数据结构,那么我将剩下哪些选项,以便一切都被概括。

4 个答案:

答案 0 :(得分:8)

是的,你可以。但由于obj的类型是一个扩展java.lang.Object的匿名类,因此您无法直接引用其字段(typevalue),只能通过反射。 / 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获取valueObject 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);