2009-07-07 9 views
6

J'écris une méthode de désérialisation qui convertit xml en un objet Java. Je voudrais le faire dynamiquement et éviter d'écrire des références codées en dur à des types spécifiques.Comment instancier une ArrayList <?> et ajouter un élément par réflexion avec Java?

Par exemple, il s'agit d'une version simplifiée d'une de mes classes.

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

Voici une version dépouillée de la méthode:

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

appel à cette méthode ressemblerait à ceci:

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

Pardonne-moi si cela est un problème trivial que je suis un développeur C# apprenant Java.

Merci!

+0

Pouvez-vous fournir un exemple du fichier XML aussi? – CookieOfFortune

+0

Que se passe-t-il si subObjects est déclaré en tant qu'interface (comme une liste)? –

Répondre

7

devrait être quelque chose d'assez près:

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

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

add.invoke(list, addToAddToList); 

Hope this helps.

+0

Merci, c'est ce que je cherchais. Pouvez-vous également expliquer comment je pourrais obtenir les informations de type pour SubObject dans l'instance de la liste? – user82334

+0

C'est le bit qui n'est pas présent, les informations de type générique pour les collections ne sont pas disponibles à l'exécution en Java. Les génériques sont implémentés dans le compilateur. –

+0

Je suppose que le bit que vous recherchez est comment savoir quelle classe instancier pour ajouter à votre nouvel objet liste? Cette information n'est tout simplement pas disponible, vous pouvez l'ajouter vous-même en créant une annotation et en annotant le champ SubObjects, quelque chose comme @SerialisationType (SubObject.class) –

0

Dans les génériques java, il n'y a que du sucre de syntaxe et ils n'existent pas en runtime. C'est pourquoi vous ne pouvez pas créer par programmation des objets génériques en cours d'exécution. Essayez de créer une liste et une distribution non génériques (mais je ne suis pas sûr car mon expérience est limitée avec GWT).

+0

Ce n'est pas tout à fait vrai. Si vous avez une classe MyArray qui étend ArrayList , alors vous avez les informations de type à l'exécution. Aussi, il est possible d'instancier un objet à l'exécution que le code convertit en un "objet paramétré" - la distribution n'aura aucun sens et votre compilateur générera un avertissement de type vérifié –

+0

@Oxbow: Une classe va stocker le type paramétré de son signatures de méthode au moment de l'exécution. Une collection individuelle ne je crois pas. – Jherico

0

Vous devrez créer un brutList (c'est-à-dire sans paramètres de type).

List subs = deserialize(...); 

Si vous deviez définir la dactylographiée première List de votre classe directement:

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

Bien que le compilateur émet un avertissement, il est le code juridique de Java et fonctionnera très bien à l'exécution parce que le les informations de type paramètre sont perdues (c'est-à-dire qu'au moment de l'exécution, il n'y a pas de différence entre un List et un List<SomeClass>). Vous pouvez bien sûr le définir également.

3

Il semble que le vrai problème ici passe du XML aux objets Java. Si tel est le cas (et puisque vous êtes nouveau à Java), une meilleure solution que vos propres modèles peut être d'étudier les technologies existantes telles que:

Questions connexes