2010-06-10 4 views
7

Je veux définir la classe suivante en tant que tels:Est-ce une limitation avec Generics en Java?

public class CollectionAttribute<E extends Collection<T>> { 
    private String name; 
    private E value; 
    public CollectionAttribute(String name, E value) { 
     this.name = name; 
     this.value = value; 
    } 

    public E getValue() { return value; } 

    public void addValue(T value) { value.add(T); } 
} 

Ce ne sera pas compilé (cannot resolve symbol T). Si je remplace la déclaration de classe ce qui suit:

public class CollectionAttribute<E extends Collection<?>> 

Alors je ne peux pas référence au type de la collection paramétrisé. Est-ce que je manque quelque chose ou ai-je atteint une limitation avec des génériques en Java?

Répondre

13

Vous devez ajouter un second paramètre générique T:

public class CollectionAttribute<T, E extends Collection<T>> { 
    private String name; 
    private E values; 
    public CollectionAttribute(String name, E values) { 
     this.name = name; 
     this.values = values; 
    } 

    public E getValue() { return value; } 

    public void addValue(T value) { values.add(value); } 
} 

Comme Nathan a souligné, vous pouvez aussi ne pas écrire value.add(T).

+0

: -o Toute explication succincte pourquoi? – OscarRyz

+0

@Support: Sinon, il n'y a pas de type 'T'. – SLaks

+0

N'est-ce pas redondant? Maintenant, je dois spécifier mon T deux fois quand je crée cet objet :( –

7

Votre exemple de classe présente deux problèmes. La première est que vous devez déclarer ce que T signifie, ce qui signifie qu'il doit être inclus dans les génériques pour la classe, ou être un vrai type de classe. Dans ce cas, vous voulez probablement

public class CollectionAttribute<T, E extends Collection<T>> 

Le deuxième problème, que vous auriez probablement trouvé si vous obtenu le compilateur passé le premier est que votre corps de méthode addValue tente d'ajouter le type T à la collection , plutôt que cette valeur:

public void addValue(T value) { this.value.add(value); }