2009-07-07 213 views
6

我正在编写一个将xml转换为Java对象的反序列化方法。我想动态地做到这一点,并避免编写特定类型的硬编码引用。如何实例化ArrayList <?>并通过Java反射添加项目?

例如,这是我的一个类的简化版本。

public class MyObject { 
    public ArrayList<SubObject> SubObjects = new ArrayList<SubObject>(); 
} 

下面是该方法的一个精简版:

public class Serializer {  
    public static <T> T fromXml(String xml, Class<T> c) { 
     T obj = c.newInstance();  
     Field field = obj.getClass().getField("SubObjects");  
     //help : create instance of ArrayList<SubObject> and add an item 
     //help#2 : field.set(obj, newArrayList); 

     return obj; 
    } 
} 

调用此方法应该是这样的:

MyObject obj = Serializer.fromXml("myxmldata", MyObject.class); 

原谅我,如果这是一个很重要的问题,因为我一位学习Java的C#开发人员。

谢谢!

+0

你能提供一个XML文件的例子吗? – CookieOfFortune 2009-07-07 16:48:05

+0

如果subObjects被声明为接口(如List)会怎么样? – 2009-07-07 19:29:22

回答

7

应该是相当接近的东西:

Object list = field.getType().newInstance(); 

Method add = List.class.getDeclaredMethod("add",Object.class); 

add.invoke(list, addToAddToList); 

希望这有助于。

0

在java泛型只是语法糖,它们不存在于运行时。这就是为什么你不能在运行时以编程方式创建通用对象的原因。尝试创建非通用列表并施放(但我不确定,因为我的经验受限于GWT)。

+0

这不完全正确。如果你有一个扩展ArrayList 的类MyArray,那么你在运行时确实有类型信息。另外,它可能在运行时实例化一个代码转换为“参数化对象”的对象 - 这种转换将毫无意义,但编译器会生成一个类型检查警告 – 2009-07-07 16:52:06

0

您必须创建一个原始类型List(即没有类型参数)。

List subs = deserialize(...); 

如果你要设置的原始类型化List你的类直接:

obj.setSubObjects(subs); //You'll get an "unchecked cast" warning at compile time 

虽然编译器会发出警告,它是合法的Java代码,并在运行时会运行得很好,因为参数类型信息丢失(即在运行时,ListList<SomeClass>之间没有差异)。你当然也可以反思。

3

看起来这里真正的问题是从XML到Java对象。如果是这样的话(因为你是新来的Java),比滚动自己一个更好的解决方案可能是调查现有技术,如:

相关问题