2010-10-06 7 views
1

Je cherche une solution pour instancier et retourner un vecteur (ou sth comparable) de classes.Comment retourner un vecteur de classes héritées?

Ma tentative ressemble à ceci (Heritage étend SuperClass):

public Vector<? extends SuperClass> getAssignableClasses() 
{ 
Vector<? extends SuperClass> out = new Vector<SuperClass>(); 
out.add(Heritage.class); //does NOT work, IDE shows error message 

return out; 
} 

La déclaration de la liste semble être erronée. Je suppose que je peux seulement ajouter des objets à une liste, mais comment puis-je ajouter des classes en utilisant des génériques?

Merci d'avance!

+2

Un peu hors sujet (d'où un commentaire), mais utilisez ArrayList pas Vector. Vector synchronise ses méthodes et est donc beaucoup plus lent. Il n'y a pratiquement aucune raison d'utiliser Vector même dans un code multithread, sauf pour la rétrocompatibilité. – locka

+0

J'irais plus loin: ** Il n'y a pratiquement aucune raison de jamais utiliser Vector **. Déjà. Nor Hashtable, Enumeration et quelques autres classes héritées. –

Répondre

1

Je n'ai pas fait cela depuis un moment, mais n'est pas le mot-clé 'super' à utiliser lorsque vous avez besoin d'ajouter des choses? :)

Here est un tutoriel :)

+0

Le problème ici est qu'il n'y a pas d'objets à ajouter mais seulement des classes comme il est dit "out.add (Heritage.class);" Je cherche un moyen de créer une liste de classes – Bernd

0

Je pense que le problème est que vous dites java pour faire un vecteur avec des objets d'un type dérivé de superclasse. Et puis vous ajoutez une classe pas un objet. Une solution sale serait de faire un vecteur de classe et de test en ajoutant si c'est une sous-classe.

1

Vous essayez d'ajouter une instance de Class - c'est-à-dire Heritage.class. Votre Vector ne permet que des sous-classes de SuperClass.

Vous devez ajouter un objet new Heritage(), mais vous devez en construire un.

1

Le problème est que vous essayez d'ajouter une classe au vecteur (classe Heritage.class) au lieu d'un objet avec la classe appropriée. Quelque chose comme suit devrait fonctionner:

public Vector<? extends SuperClass> getAssignableClasses() 
{ 
    Vector<? extends SuperClass> out = new Vector<SuperClass>(); 
    out.add(new Heritage()); //this line is changed 
          //add appropriate constructor parameters as necessary 
    return out; 
} 

Mise à jour Je relis votre question. Pour revenir les classes concrètes, vous aurez besoin de quelque chose comme suit (je ne l'ai pas essayer):

public Vector<? extends SuperClass.class> getAssignableClasses() 
    { 
    Vector<? extends SuperClass> out = new Vector<SuperClass>(); 
    out.add(Heritage.class); //does NOT work, IDE shows error message 
    return out; 
    } 
1

Ou -as autres ont signalé OUT- vous devez ajouter une instance du Patrimoine: new Heritage() ...

ou vous devez déclarer correctement le vecteur pour les classes de magasin au lieu des instances:

Vector<Class<? extends SuperClass>> 

Class<? extends SuperClass> signifie SuperClass.class ou tout descendant ...

Important: Utilisez List au lieu de Vector. Il est l'interface de la liste recomended depuis Java 1.3 :)

Ajouté: J'ai vérifié le code dans votre commentaire et il semble compiler ok:

import java.util.Vector; 

public class SuperClass { 
    public static void main() throws Exception { 
     Vector<Class<? extends SuperClass>> vector = new Vector<Class<? extends SuperClass>>(); 
     vector.add(SuperClass.class); 
     vector.add(Heritage.class); 
    } 

    public Vector<Class<? extends SuperClass>> getAssignableClasses() { 
     Vector<Class<? extends SuperClass>> out = new Vector<Class<? extends SuperClass>>(); 
     out.add(Heritage.class); 
     return out; 
    } 
} 

class Heritage extends SuperClass { 

} 
+0

Ouais, c'est ce que je viens de découvrir :-) Mais toujours la signature de la méthode semble être fausse: public Vector > getAssignableClasses() { Vecteur > out = nouveau Vecteur >(); Out.add (ZahnradComponent.class); retournez; } – Bernd

+0

Vous pouvez utiliser ArrayList en tant qu'implémentation (ou LinkedList ... mais ArrayList suffira la plupart du temps). – helios

1

Vector est une ancienne classe un peu dépréciée.Je vais utiliser une version de liste générique à la place:

public static List<Class<?>> getAssignableClasses(final Object o){ 
    final List<Class<?>> list; 
    if(o == null){ 
     list = Collections.emptyList(); 
    } else{ 
     list = new ArrayList<Class<?>>(); 
     Class<?> tmp = o.getClass(); 
     do{ 
      list.add(tmp); 
      tmp = tmp.getSuperclass(); 
     } while(tmp != null); 
    } 
    return list; 
} 

Et en bonus, voici une méthode qui rassemble toutes les interfaces assignables selon la méthode ci-dessus:

public static List<Class<?>> getAssignableInterfaces(final Object o){ 
    final List<Class<?>> result; 
    final List<Class<?>> assignableClasses = getAssignableClasses(o); 
    if(assignableClasses.isEmpty()){ 
     result = Collections.emptyList(); 
    } else{ 
     final Set<Class<?>> interfaces = 
      new LinkedHashSet<Class<?>>(assignableClasses.size() * 2); 
     for(final Class<?> clazz : assignableClasses){ 
      interfaces.addAll(Arrays.asList(clazz.getInterfaces())); 
     } 
     result = new ArrayList<Class<?>>(interfaces); 
    } 
    return result; 
} 

Test:

public static void main(final String[] args){ 
    final Map<String, String> map = 
     new ConcurrentHashMap<String, String>(); 
    System.out.println(getAssignableClasses(map)); 
    System.out.println(getAssignableInterfaces(map)); 
} 

sortie:

[class java.util.concurrent.ConcurrentHashMap, class java.util.AbstractMap, class java.lang.Object] 
[interface java.util.concurrent.ConcurrentMap, interface java.io.Serializable, interface java.util.Map] 
Questions connexes