2009-07-09 6 views
3

Je suis toujours aux prises avec des médicaments génériques. Je ne sais pas pourquoi cela rend ma folie. J'ai un vieux problème que j'ai plusieurs fois.Lutte contre les génériques et les classes

class Father { 
    ... 
} 

class Child1 extends Father { 
    ... 
} 

class Child2 extends Father { 
    ... 
} 

public class TestClass { 
    private static Class<? extends Father>[] myNiceClasses = new Class<? extends Father>[] { 
     Child1.class, 
     Child2.class 
    } 
} 

qui ne pas travail. Le compilateur se plaint comme ceci:

Cannot create a generic array of Class<? extends Father> 

Si je change la ligne de tableau (défectueuse) à

private static Class<Father>[] myNiceClasses = new Class<Father>[] { 

le même message d'erreur se produit, mais aussi ce message est ajouté:

Type mismatch: cannot convert from Class<Child1> to Class<Father> 

La seule version fonctionnelle est cette ligne:

private static Class<?>[] myNiceClasses = new Class<?>[] { 

Cette solution n'est pas satisfaisante, car vous ne pouvez pas lancer si facilement. Donc, ma question est: Comment résoudre ce problème? Où est le noeud dans mon cerveau?

Répondre

8

C'est parce que Java ne supporte pas la création de tableau générique. Les génériques fonctionnent mieux avec les collections. Vous pouvez donc utiliser ArrayList pour résoudre votre problème:

 ArrayList<Class<? extends Father>> myNiceClasses = new ArrayList<Class<? extends Father>>(); 
     myNiceClasses.add(Child1.class); 
     myNiceClasses.add(Child2.class); 
+0

+1. Utilisez des génériques avec des collections, pas des tableaux. – seanmonstar

4

Qu'est-ce que le fil de quant_dev lié dit est que les tableaux génériques ne peuvent pas être créés parce qu'ils ne peuvent pas garantir la sécurité de type. Vous pouvez vous retrouver avec des choses dans le tableau que les génériques ne permettent pas. La façon la plus propre que je connaisse quand même le faire est:

private static Class<? extends Father>[] myNiceClasses = 
     (Class<? extends Father>[]) new Class<?>[] {}; 
1

Les génériques et les matrices sont une combinaison à éviter. Le fait que le compilateur n'aime pas que vous créiez un tableau générique est un artefact du fait que Java Generics est un ajout à la langue, et parfois vous pouvez voir la jointure. Un autre exemple est Exceptions, vous ne pouvez pas non plus combiner ceux avec des génériques.

Je suggère d'éviter les tableaux dans des situations comme celle-ci. Utilisez une liste générique à la place.

1

Cela est dû à quelque chose appelé effacement de type. Le compilateur Java efface toutes les informations génériques au cours du processus de compilation. (Ceci est dû au fait que les génériques constituaient un ajout tardif à la langue, et Sun a décidé de ne pas modifier la JVM pour la rétrocompatibilité, ce qui signifie que la langue connaît les génériques, mais pas la JVM). ne connaît pas le type générique à l'exécution, il ne peut pas instancier un tableau de ce type générique. Dans votre cas, le mieux qu'il peut faire est d'instancier un tableau du type brut Class.

Dans des cas comme celui-ci, il est préférable d'utiliser le framework de gestion des collections, qui supporte entièrement les génériques. En résumé: les génériques et les matrices ne se mélangent pas.

0

Alternativement, comme dit amit.dev, vous pouvez vouloir utiliser une liste.Dans ce cas, en supposant que le champ myNiceClasses est censé être une constante, vous pouvez utiliser Collections.unmodifiableList pour vous assurer que la liste ne peut pas être modifié:

private static final List<? extends Father> myNiceClasses; 
static { 
    ArrayList<? extends Father> l = new ArrayList<? extends Father>(); 
    l.add(Child1.class); 
    l.add(Child2.class); 
    myNiceClasses = Collections.unmodifiableList(l); 
} 

Il est assez bavard, mais a l'avantage d'être tout à fait constante et par conséquent plus facile à raisonner.

Questions connexes