2009-07-07 11 views
6

Estoy escribiendo un método de deserialización que convierte XML a un objeto Java. Me gustaría hacer esto de forma dinámica y evitar escribir referencias codificadas de tipos específicos.¿Cómo crear una instancia de ArrayList <?> y agregar un elemento a través de la reflexión con Java?

Por ejemplo, esta es una versión simplificada de una de mis clases.

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

Aquí es una versión simplificada del método:

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

llamada a este método sería el siguiente:

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

Perdóname si esto es un problema trivial como soy un desarrollador de C# aprendiendo Java.

Gracias!

+0

¿Puede proporcionar un ejemplo del archivo XML también? – CookieOfFortune

+0

¿Qué pasa si subObjects se declara como una interfaz (como una lista)? –

Respuesta

7

debe ser algo bastante cercano a:

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

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

add.invoke(list, addToAddToList); 

Espero que esto ayude.

+0

Gracias, esto es lo que estaba buscando. ¿También puede explicar cómo podría obtener la información de tipo para SubObject en la instancia de la lista? – user82334

+0

Ese es el bit que no está presente, la información de tipo genérico para colecciones no está disponible en tiempo de ejecución en Java. Los genéricos se implementan en el compilador. –

+0

Supongo que lo poco que buscas es cómo saber qué clase crear una instancia para agregar a tu nuevo objeto de lista? Esa información simplemente no está disponible, puede agregarla auto creando una anotación y anotando el campo SubObjects con ella, algo así como @SerialisationType (SubObject.class) –

0

En java generics son solo azúcar de sintaxis y no existen en tiempo de ejecución. Esta es la razón por la que no puede crear objetos genéricos mediante programación en tiempo de ejecución. Intente crear una lista no genérica y un elenco (sin embargo, no estoy seguro ya que mi experiencia es limitada con GWT).

+0

Eso no es del todo cierto. Si tiene una clase MyArray que amplía ArrayList , entonces tiene la información de tipo en tiempo de ejecución. Además, es posible crear una instancia de un objeto en tiempo de ejecución que el código arroja a un "objeto parametrizado"; sin embargo, el molde no tendrá sentido y el compilador generará un tipo de advertencia marcada –

+0

@Oxbow: una clase almacenará el tipo parametrizado de su firmas de métodos en tiempos de ejecución. Una colección individual no creo. – Jherico

0

Deberá crear un tipografía sin procesarList (es decir, sin parámetros de tipo).

List subs = deserialize(...); 

Si se va a establecer el mecanografiado prima List en su clase directamente:

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

Aunque el compilador emitirá una advertencia, que es el código legal de Java y funcionará bien en tiempo de ejecución debido a que el la información del tipo de parámetro se pierde (es decir, en el tiempo de ejecución, no hay diferencia entre List y List<SomeClass>). Por supuesto, también puede configurarlo de manera reflexiva.

3

Parece que el verdadero problema aquí va de XML a objetos Java. Si ese es el caso (y ya que usted es nuevo en Java), una solución mejor que rodar su propia puede ser para investigar las tecnologías existentes, tales como:

Cuestiones relacionadas