¿Cómo puedo requerir que un parámetro genérico sea una enumeración que implemente una interfaz?

3 minutos de lectura

Avatar de usuario de Sbodd
Sbodd

No estoy 100% convencido de que sea una buena idea, pero hoy me encontré con un código que actualmente está implementado como:

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

  Map<T, Integer> mValueMap;
}

dónde MyWidget luego ofrece métodos que usan mValueMap para convertir el pasado Enum hacia/desde un Integer.

Lo que estaba considerando hacer era tratar de refactorizar esto, para declarar 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 se parecía vagamente a esto:

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

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

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

¡Gracias por adelantado!

Avatar de usuario de Michael Myers
Michael Myers

Usa un ‘&‘ en cambio:

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

los JLS llama a esto un “tipo de intersección”, pero no puedo encontrar ninguna mención en los tutoriales de Java. Solo diré que hace exactamente lo que deseabas que “extends” haría.

Además, debo mencionar que puede tener tantos tipos como desee en el tipo de intersección. Entonces, si quisieras, podrías hacer:

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

[Note: this code sample should not be construed as an endorsement of the Cloneable interface; it was merely handy at the time.]

  • La sintaxis & es ordenada, pero encuentro que su uso generalmente se convierte en un olor a código, y es una indicación de que algo no está del todo bien con su modelo.

    – Skaffman

    1 de julio de 2009 a las 19:33

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

    – Michael Myers

    1 de julio de 2009 a las 19:41

  • Gracias. Tu publicación de alguna manera me hizo darme cuenta de que lo que realmente necesitaba era algo así como… doSomething(Enum<? extends SomeInterface>)

    – Jörg

    8 de junio de 2011 a las 8:17


  • @skaffmann si encuentra tiempo para compartir su experiencia relacionada con WRT el código huelete lo agradecería mucho

    – Jörg

    8 de junio de 2011 a las 8:17


  • +10 Nunca me habría dado cuenta de esto por mi cuenta. La única forma de manejar enumeraciones con interfaces.

    –David Lynch

    11/09/2012 a las 21:57

El material JSR 203 (nuevo nuevo IO) para JDK 7 está haciendo mucho uso de las enumeraciones que implementan interfaces (por ejemplo: http://openjdk.java.net/projects/nio/javadoc/java/nio/file/FileVisitOption.html) para permitirles un margen de maniobra en el futuro para futuros conjuntos adicionales de opciones de enumeración. Así que ese es un enfoque factible y obviamente uno que fue elegido después de mucho pensar en un gran proyecto de Sun.

  • Pulcro. Esperemos que Java 7 aparezca antes de que mi barba se vuelva gris.

    – Skaffman

    1 de julio de 2009 a las 20:16

  • Al escribir 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 haya visto en ningún otro lado. Algo con un 7 en el nombre se lanzará en 2010, estoy bastante seguro. Si será “Java 7” respaldado por el JCP, no lo sé. Solo Oracle puede responder eso ahora…

    – Álex Miller

    1 de julio de 2009 a las 20:51

  • docs.oracle.com/javase/8/docs/api/java/nio/file/…

    – nessa.gp

    15 de abril de 2020 a las 8:02

¿Ha sido útil esta solución?