web-dev-qa-db-fra.com

Java Cartes génériques génériques avec plusieurs classes

Je souhaite avoir un objet Class, mais je veux forcer la classe qu'elle représente à étendre la classe A et à implémenter l'interface B.

Je peux faire:

Class<? extends ClassA>

Ou:

Class<? extends InterfaceB>

mais je ne peux pas faire les deux. Y a-t-il un moyen de faire cela?

360
Alex Beardsley

En fait, vous pouvez faire ce que vous voulez. Si vous souhaitez fournir plusieurs interfaces ou une interface classe plus, vous devez que votre caractère générique ressemble à ceci:

_<T extends ClassA & InterfaceB>
_

Reportez-vous à la section Didacticiel des génériques sur Sun.com, plus précisément à la section Paramètres de type borné , au bas de la page. Vous pouvez en fait répertorier plus d’une interface si vous le souhaitez, en utilisant _& InterfaceName_ pour chacune d’elles.

Cela peut devenir arbitrairement compliqué. Pour démontrer, voir la déclaration JavaDoc de Collections#max , qui (enveloppée sur deux lignes) est:

_public static <T extends Object & Comparable<? super T>> T
                                           max(Collection<? extends T> coll)
_

pourquoi si compliqué? Comme indiqué dans la FAQ Java Generics: Pour préserver la compatibilité binaire .

Il semble que cela ne fonctionne pas pour la déclaration de variable, mais cela fonctionne lorsque vous définissez une limite générique sur une classe. Ainsi, pour faire ce que vous voulez, vous devrez peut-être sauter à travers quelques cerceaux. Mais tu peux le faire. Vous pouvez faire quelque chose comme ceci, en mettant une limite générique sur votre classe, puis:

_class classB { }
interface interfaceC { }

public class MyClass<T extends classB & interfaceC> {
    Class<T> variable;
}
_

pour obtenir variable qui a la restriction souhaitée. Pour plus d'informations et d'exemples, consultez la page 3 de Génériques dans Java 5. . Notez que dans _<T extends B & C>_, le nom de la classe doit figurer en premier, suivi des interfaces. Et bien sûr, vous ne pouvez lister qu'une seule classe.

567
Eddie

Vous ne pouvez pas le faire avec des paramètres de type "anonymes" (c'est-à-dire des caractères génériques utilisant ?), mais vous pouvez le faire avec des paramètres de type "nommés". Déclarez simplement le paramètre type au niveau de la méthode ou de la classe.

import Java.util.List;
interface A{}
interface B{}
public class Test<E extends B & A, T extends List<E>> {
    T t;
}
16
user2861738

Un paramètre de type peut avoir plusieurs limites. Par exemple

public static <T extends Number & Comparable<T>> T maximum(T x, T y, T z)

La T est un paramètre de type transmis à la classe générique Box et doit être un sous-type de la classe Number et doit implémenter une interface comparable. Si une classe est passée comme liée, elle devrait l'être avant l'interface, sinon une erreur de compilation se produirait.

public static <T extends Number & Comparable<T>> T maximum(T x, T y, T z) {
    T max = x;      
    if(y.compareTo(max) > 0) {
        max = y;   
    }

    if(z.compareTo(max) > 0) {
        max = z;                    
    }
    return max;      
}

Lire la suite ici

0
yoAlex5