español - wildcard en java
Java Generics Wildcarding con múltiples clases (2)
Quiero tener un objeto de clase, pero quiero forzar cualquier clase que represente para extender la clase A e implementar la interfaz B.
Puedo hacer:
Class<? extends ClassA>
O:
Class<? extends InterfaceB>
pero no puedo hacer ambas cosas. ¿Hay alguna forma de hacer esto?
En realidad, puedes hacer lo que quieras. Si desea proporcionar múltiples interfaces o una clase más interfaces, debe hacer que su comodín tenga un aspecto similar al siguiente:
<T extends ClassA & InterfaceB>
Consulte el Tutorial de genéricos en sun.com, específicamente la sección Parámetros de tipo delimitado , en la parte inferior de la página. Si lo desea, puede enumerar más de una interfaz, utilizando & InterfaceName
para cada una de las que necesite.
Esto puede complicarse arbitrariamente. Para demostrarlo, vea la declaración JavaDoc de Collections#max
, que (envuelta en dos líneas) es:
public static <T extends Object & Comparable<? super T>> T
max(Collection<? extends T> coll)
¿Por qué tan complicado? Como se dijo en las Preguntas frecuentes de Java Generics: Para preservar la compatibilidad binaria .
Parece que esto no funciona para la declaración de variables, pero funciona cuando se coloca un límite genérico en una clase. Por lo tanto, para hacer lo que quieras, es posible que tengas que saltar a través de algunos aros. Pero puedes hacerlo. Puedes hacer algo como esto, poniendo un límite genérico en tu clase y luego:
class classB { }
interface interfaceC { }
public class MyClass<T extends classB & interfaceC> {
Class<T> variable;
}
para obtener la variable
que tiene la restricción que deseas. Para obtener más información y ejemplos, consulte la página 3 de Genéricos en Java 5.0 . Tenga en cuenta que en <T extends B & C>
, el nombre de la clase debe aparecer primero, y luego las interfaces. Y, por supuesto, solo puedes enumerar una sola clase.
No puede hacerlo con parámetros de tipo "anónimos" (es decir, comodines que usan ?
), Pero puede hacerlo con parámetros de tipo "con nombre". Simplemente declare el parámetro de tipo a nivel de método o clase.
import java.util.List;
interface A{}
interface B{}
public class Test<E extends B & A, T extends List<E>> {
T t;
}