Genéricos de Java con una clase y una interfaz: juntos
Quiero tener un objeto Clase, pero quiero forzar que cualquier clase que represente extienda la clase A e implemente 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 se vea así:
<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. De hecho, puede enumerar más de una interfaz si lo desea, utilizando & InterfaceName
cada una que necesite.
Esto puede volverse arbitrariamente complicado. Para demostrarlo, consulte la declaración JavaDoc de Collections#max
, que (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 dice en las preguntas frecuentes sobre genéricos de Java: Para preservar la compatibilidad binaria .
Parece que esto no funciona para la declaración de variables, pero sí funciona cuando se pone un límite genérico en una clase. Por lo tanto, para hacer lo que desea, es posible que deba superar algunos obstáculos. Pero puedes hacerlo. Puedes hacer algo como esto, poniendo un límite genérico a tu clase y luego:
class classB { }
interface interfaceC { }
public class MyClass<T extends classB & interfaceC> {
Class<T> variable;
}
para conseguir variable
que tenga la restricción que quieras. 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 ir primero y luego las interfaces. Y, por supuesto, solo puedes enumerar una única clase.
No puede hacerlo con parámetros de tipo "anónimos" (es decir, comodines que usan ?
), pero puede hacerlo con parámetros de tipo "nombrados". 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;
}