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

Java 使用反射检索对象的数据类型,java,reflection,Java,Reflection,我初始化了一个对象,如下所示: Object obj = new Object(){ final String type = "java.lang.Integer"; final Object value = 6; }; 我想将此对象重新创建为: Integer i = 6; 是否有任何方法可以获取obj对象的type字段,并使用反射创建一个新实例并在其中输入值 编辑:扩展此问题后,我发现如果我将对象存储在文件中并使用Jackson从文件中检索它,请使用以下命令: Reader

我初始化了一个对象,如下所示:

Object obj  = new Object(){
  final String type = "java.lang.Integer";
  final Object value = 6;
};
我想将此对象重新创建为:

 Integer i = 6;
是否有任何方法可以获取
obj
对象的
type
字段,并使用反射创建一个新实例并在其中输入值

编辑:扩展此问题后,我发现如果我将对象存储在文件中并使用Jackson从文件中检索它,请使用以下命令:

Reader reader = new Reader();
MyClass[] instances = reader.readValue(fileName);
MyClass
定义为:

class MyClass{

  List<Object> fields;
  .
  .
  .
}

但是,当我查看表达式
field.getClass()
时,它将
LinkedHashMap
作为其类。我不明白为什么,如果对象在内部被视为
Map
,那么如果我想使用反射而不使用具体的数据结构来实现它,那么我还有什么选择余地,这样一切都可以通用化。

是的,您可以使用
Class.forName

例如,代替整数,考虑一个人——


要从Person.Class创建Person对象,可以执行以下操作-

final Person p = Person.class.getConstructor(Integer.class, String.class).newInstance(age, name);

这将从对象中检索
type
字段的值:
obj.getClass().getDeclaredField(“type”).get(obj)

只需查看新更新的代码:

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();
    }
}
注意:从问题中获得帮助


更新:现在从
对象obj
获取
类型
是的,您可以。但是由于
obj
的类型是一个扩展
java.lang.Object
的匿名类,因此只能通过反射,不能直接引用其字段(
type
value

以下是您可以如何执行此操作的代码:

    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);

大概但是对于
i
,您只需要得到
obj.value
;我的意思是你想如何使用这个实例?@Elliott:我的基本目的是,如果我在给定的代码中有一个像
obj
这样的对象,我首先想得到像
obj.type
这样的类型,然后可能使用
Class.forName.newInstance
来获得Integer的实例,然后使用构造函数尝试在
i
中设置
obj.value
,我知道,这就是创建一些
i
的方法。现在,您如何处理
i
?因为我怀疑你想把
I
传递给某个东西。也许可以打印出来?是的我有。。。我已经更新了我的代码,但是我想知道它是否是person类。实际上,Person.class是obj的my type字段将提供给我的东西,使用该返回类型,我将能够使用您建议的方法获取实例。是的,您可以将任何类的名称作为
类型传递。请看我编辑的答案。是的,这是我将尝试做的,但为什么问题是如何从
obj
?@Sourabh中检索
类型
?-我在上面的答案中向您展示的方式。这是我一直在寻找的东西。你能告诉我obj.getClass().getField(“type”)和
obj.getClass().getDeclaredField(“type”)之间的区别吗?为什么后者有效而前者无效?
getField
只搜索公共字段,
getDeclaredField
搜索所有类型的字段(公共、私有、受保护、默认)。您给出的答案绝对正确,但由于巴纳南在您之前几分钟发布了消息,我必须给他正确的答案。:)
final Person p = Person.class.getConstructor(Integer.class, String.class).newInstance(age, name);
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();
    }
}
    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);