[英]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
的匿名類,因此不能直接引用其字段( 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);
只需看看新的更新代碼:
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
獲取type
和value
。
是的,您可以使用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.