2009-07-01 11 views
39

No estoy 100% convencido de que esta es una buena idea, pero me encontré con algo de código hoy que está implementado actualmente como:¿Cómo puedo exigir que un parámetro genérico sea una enumeración que implemente una interfaz?

class MyWidget <T extends Enum<T> > { 
    MyWidget(Map<T, Integer> valueMap) { 
    mValueMap = valueMap; 
    } 

    Map<T, Integer> mValueMap; 
} 

donde MyWidget continuación, ofrece métodos que utilizan mValueMap para convertir el pasado en Enum a/desde un Integer.

Lo que estaba pensando en hacer estaba tratando de refactorizar esto, así que me declaro mi enumeración:

interface MyInterface { 
    public Integer getValue(); 
} 

enum MyEnum implements MyInterface { 
    foo, bar; 
    public Integer getValue() { 
    return ordinal(); 
    } 
} 

Y entonces sería capaz de reescribir MyWidget en algo que parecía vagamente como esto:

public class MyWidget<T extends Enum<T> extends MyInterface> { 
    ... 
} 

y entonces sería capaz de llamar al método de getValue()MyInterface en T de tipo objetos dentro MyWidget. El problema, por supuesto, es que "<T extends Enum<T> extends MyInterface>" no es una sintaxis válida. ¿Hay alguna manera de lograr esto?

No quiero simplemente tener MyWidget<T extends MyInterface>, porque también es importante que T sea una enumeración.

¡Gracias de antemano!

Respuesta

77

uso de un '&' en su lugar:

public class MyWidget<T extends Enum<T> & MyInterface> { 
    ... 
} 

Los JLS llamadas a esto un "tipo de intersección", pero no puedo encontrar ninguna mención de ella en los tutoriales de Java. Solo diré que hace exactamente lo que deseaba que "extends" hiciera.

Además, debo mencionar que puede tener tantos tipos como desee en el tipo de intersección. Así que si quería, se podía hacer:

public class MyWidget<T extends Enum<T> & MyInterface & Serializable & Cloneable> { 
    ... 
} 

[Nota: este ejemplo de código no debe interpretarse como una aprobación de la interfaz Cloneable; no era más útil en el momento]

+0

La sintaxis & es nítida, pero me parece que usarla generalmente se convierte en un olor a código, y es una indicación de que algo no está bien con su modelo. – skaffman

+2

Tiendo a estar de acuerdo (creo que lo he usado tal vez una o dos veces, si es eso). Pero en el caso de las enums que implementan una interfaz, creo que es apropiado. –

+0

¡Excelente! Eso es exactamente lo que estaba buscando. Muchas gracias! – Sbodd

1

El 203 (nueva nueva IO) cosas JSR para JDK 7 está haciendo una gran cantidad de uso de enumeraciones que implementan las interfaces (por ejemplo: http://openjdk.java.net/projects/nio/javadoc/java/nio/file/FileVisitOption.html). que les permita un margen de maniobra en el futuro para futuros conjuntos adicionales de opciones enum. Entonces, ese es un enfoque factible y, obviamente, uno que fue elegido después de una gran cantidad de pensamiento en un gran proyecto de Sun.

+0

aseado.Con suerte, java 7 aparecerá antes de que mi barba se ponga gris. – skaffman

+0

Escribo una pequeña cantidad de código que usa estas cosas, mi impresión es que es un poco raro. No puedo decir que lo he visto en otro lado. Algo con un 7 en el nombre se lanzará en 2010, estoy bastante seguro. Ya sea que se trate de "Java 7" respaldado por el JCP, no lo sé. Solo Oracle puede responder eso ahora ... –

Cuestiones relacionadas