簡體   English   中英

使用反射檢索對象的數據類型

[英]Retrieving the data type for an object using reflection

我有一個初始化的對象:

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;
  .
  .
  .
}

現在我正在迭代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 ,如果我想用反射做而不使用具體的數據結構,那么我將剩下哪些選項,以便一切都是通用的。

是的你可以。 但由於obj的類型是一個擴展java.lang.Object的匿名類,因此不能直接引用其字段( typevalue ),只能通過反射。

以下是您可以執行此操作的代碼:

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

只需看看新的更新代碼:

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

注意:這個問題得到幫助。

更新:現在從Object obj獲取typevalue

是的,您可以使用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);

這將從您的對象中檢索type字段的值: obj.getClass().getDeclaredField("type").get(obj);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM