2009-07-07 12 views
6

Sto scrivendo un metodo di deserializzazione che converte xml in un oggetto Java. Mi piacerebbe farlo dinamicamente ed evitare di scrivere riferimenti codificati su tipi specifici.Come istanziare un ArrayList <?> e aggiungere un elemento tramite riflessione con Java?

Ad esempio questa è una versione semplificata di una delle mie classi.

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

Ecco una versione ridotta del metodo:

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

chiamata a questo metodo sarebbe simile a questa:

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

perdonatemi se questo è un problema banale come lo sono io uno sviluppatore C# che apprende Java.

Grazie!

+0

Potete fornire anche un esempio del file XML? – CookieOfFortune

+0

Cosa succede se subObjects è dichiarato come interfaccia (come ad esempio un elenco)? –

risposta

7

dovrebbe essere qualcosa di abbastanza vicino a:

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

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

add.invoke(list, addToAddToList); 

Spero che questo aiuti.

+0

Grazie, questo è quello che stavo cercando. Puoi anche spiegare come posso ottenere le informazioni sul tipo per SubObject nell'istanza dell'elenco? – user82334

+0

Questo è il bit che non è presente, le informazioni di tipo generico per le raccolte non sono disponibili in fase di esecuzione in Java. I generici sono implementati nel compilatore. –

+0

Immagino che il bit che cerchi sia come sapere quale classe di istanziare aggiungere al tuo nuovo oggetto lista? Queste informazioni non sono disponibili, puoi aggiungerle creando un'annotazione e annotando il campo SubObjects con esso, qualcosa come @SerialisationType (SubObject.class) –

0

In Java generics sono solo lo zucchero di sintassi e non esistono in runtime. Questo è il motivo per cui non è possibile creare oggetti generici a livello di codice in fase di runtime. Prova a creare elenchi e cast non generici (tuttavia non sono sicuro poiché la mia esperienza è limitata a GWT).

+0

Non è del tutto vero. Se hai una classe MyArray che estende ArrayList , allora hai le informazioni sul tipo in fase di esecuzione. Inoltre, è possibile istanziare un oggetto in fase di esecuzione che il codice esegue su un "oggetto parametrizzato" - il cast non avrà alcun significato e il compilatore genererà un avviso di tipo controllato –

+0

@Oxbow: una classe memorizzerà il tipo parametrizzato del suo firme di metodo a runtime. Una collezione individuale non credo. – Jherico

0

È necessario creare un codice non elaboratoList (vale a dire senza parametri di tipo).

List subs = deserialize(...); 

Se si dovesse impostare il dattiloscritto grezzo List sulla tua classe direttamente:

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

Anche se il compilatore emetterà un avviso, è il codice Java legale e funzionerà bene in fase di esecuzione in quanto il le informazioni sul tipo di parametro sono perse (ad es. in fase di esecuzione, non vi è alcuna differenza tra uno List e uno List<SomeClass>). Ovviamente puoi anche impostarlo in modo riflessivo.

3

Sembra che il vero problema qui passi dagli oggetti XML a quelli java. Se questo è il caso (e dal momento che siete nuovi a Java), una soluzione migliore di posizionare il proprio può essere di indagare le tecnologie esistenti, quali:

Problemi correlati