Tengo la siguiente interfaz:
public interface Moon {
// Enums can not extend any class in Java,
// thus I am implementing an interface
double getMass();
double getDiameter();
}
que es implementado por mis enumeraciones (omití el constructor y los métodos de aplicación)
public enum Saturn implements Moon {
ATLAS(30.2, 6.6),
PAN(28.2, 4.95);
private double Diameter;
private double Mass;
// constructor and methods implementation
}
y del mismo modo las enumeraciones de otros planetas:
public enum Mars implements Moon {
PHOBOS(22.2, 1.08),
DEIMOS(12.6, 2);
private double Diameter;
private double Mass;
// constructor and methods implementation
}
Pregunta
Tener dos cadenas:
String planetName = "Mars";
String moonName = "PHOBOS";
¿Cómo puedo obtener la enumeración particular, de una manera inteligente?
En el caso de una única clase de enumeración es un simple uso del valueOf
método, pero ¿cómo puedo comprobar todas las enumeraciones que implementan una interfaz en particular?
Moon something = <??planetName??>.valueOf(moonName);
Se puede utilizar una asignación de nombres de planetas a los tipos de enumeración relacionados, y usarlo para realizar una búsqueda.
Por ejemplo, el uso de un mapa (hay enfoques alternativos seguramente):
Map<String, Class<? extends Enum>> planetMoonTypes = new HashMap<>();
planetMoonTypes.put("Saturn", Saturn.class);
planetMoonTypes.put("Mars", Mars.class);
Con tal un mapa, se puede buscar el "PHOBOS"
valor utilizando:
Moon phobos = (Moon) Enum.valueOf(planetMoonTypes.get("Mars"), "PHOBOS");
El regreso por encima de la voluntad Mars.PHOBOS
EDIT: En cuanto a la posibilidad de añadir enumeraciones no la luna. Puede encapsular el mapa y forzar los límites apropiados. Por ejemplo, los siguientes usos de un método para que:
class MoonRegistry {
private final Map<String, Class<? extends Enum>>
planetMoonTypes = new HashMap<>();
{
this.registerEnum("Saturn", Saturn.class);
this.registerEnum("Mars", Mars.class);
}
public <T extends Enum<T> & Moon> void registerEnum(
String planetName, Class<T> cls) {
this.planetMoonTypes.put(planetName, cls);
}
public Moon findByPlanetAndName(String planet, String name) {
return (Moon) Enum.valueOf(this.planetMoonTypes.get(planet), name);
}
}
Una vez más, esta solución no puede ser de tipo seguro completamente porque hay varios subtipos de enumeración (como se puede ver, el crudo Enum
tipo es en el tipo del campo ejemplo). Pero si esto está bien encapsulado y el código utiliza ningún tipo de prima fuera de esta clase, se puede asegurar que los únicos tipos de enumeración de ejecución Moon
se añaden.