2010-11-11 35 views
3

J'ai une méthode de construction statique pour une classe "Model" qui prend une chaîne JSON et retourne une ArrayList de modèles. Je voudrais qu'il se réfère génériquement au constructeur du modèle afin que les sous-classes puissent hériter de la méthode du constructeur.Comment puis-je accéder à un constructeur Java de manière générique?

public class Model 
{ 
    protected int id; 

    public Model(String json) throws JSONException 
    { 
     JSONObject jsonObject = new JSONObject(json); 
     this.id = jsonObject.getInt("id"); 
    } 

    public static <T extends Model> ArrayList<T> build(String json) throws JSONException 
    { 
     JSONArray jsonArray = new JSONArray(json); 

     ArrayList<T> models = new ArrayList<T>(jsonArray.length()); 

     for(int i = 0; i < jsonArray.length(); i++) 
      models.add(new T(jsonArray.get(i))) 

     return models; 
    } 
} 

C'est une mise en œuvre simplifiée de la classe, la ligne concernée étant

models.add(new T(jsonArray.get(i))) 

Je sais que ce n'est pas possible, mais je voudrais écrire quelque chose qui appelle le constructeur de tout type T s'avère être. J'ai essayé d'utiliser this(), ce qui ne marche évidemment pas parce que la méthode "build" est statique et j'ai essayé d'utiliser la réflexion pour déterminer la classe de T mais j'ai été incapable de comprendre comment l'obtenir travailler. Toute aide est grandement appréciée.

Merci,

Roy

+0

Comment décidez-vous ce que la sous-classe dont vous avez besoin? Cette décision doit être formulée et écrite dans le code en quelque sorte. La décision est-elle basée sur la valeur de retour de jsonArray.get (i)? (Que retourne cette méthode, de toute façon?) – perp

Répondre

0

La façon dont il est écrit maintenant, je ne peux pas voir que le paramètre de type T dans la construction() est d'une quelconque utilité. Ne pouvez-vous pas le laisser tomber et utiliser Model à sa place? Si oui, cela résoudrait votre problème de construction.

+0

Si j'appelle "new Model (json)", cela se traduira-t-il par la sous-classe de Model quand j'en hériterai? Je vais essayer maintenant et voir – royvandewater

+0

Non, ce ne sera pas. Mais le static build() n'a aucun moyen de savoir quelle sous-classe instancier, donc une approche différente est nécessaire. – perp

1

La solution de contournement pour « instanciation dynamique » avec les génériques est de passer une allusion à la classe ou la méthode:

public class Model<T> { 
    Class<T> hint; 
    public Model(Class<T> hint) {this.hint = hint;} 

    public T getObjectAsGenericType(Object input, Class<T> hint) throws Exception { 
    return hint.cast(input); 
    } 

    public T createInstanceOfGenericType(Class<T> hint) throws Exception { 
    T result = hint.newInstance(); 
    result.setValue(/* your JSON object here */); 
    return result; 
    } 
} 

Je suis heureux de vous fournir plus d'aide/idées mais je ne suis pas sûr de ce que vous voulez atteindre avec votre solution technique.

(Note: par exemple, a un peu trop simplifié la gestion des exceptions)