Вы можете использовать сопоставление имен планет с соответствующими типами перечислений и использовать его для поиска.
Например, используя карту (есть, безусловно, альтернативные подходы):
Map<String, Class<? extends Enum>> planetMoonTypes = new HashMap<>();
planetMoonTypes.put("Saturn", Saturn.class);
planetMoonTypes.put("Mars", Mars.class);
С такой картой вы можете найти значение "PHOBOS"
, используя:
Moon phobos = (Moon) Enum.valueOf(planetMoonTypes.get("Mars"), "PHOBOS");
Выше будет возвращено Mars.PHOBOS
РЕДАКТИРОВАТЬ: Относительно способности добавлять не лунные перечисления.Вы можете инкапсулировать карту и устанавливать правильные границы.Например, следующий метод использует для этого метод:
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);
}
}
Опять же, это решение не может быть полностью безопасным с точки зрения типов, поскольку существует несколько подтипов enum (как вы можете видеть, тип raw Enum
находится втип поля экземпляра).Но если это правильно инкапсулировано и ваш код не использует необработанные типы вне этого класса, вы можете убедиться, что добавляются только перечисляемые типы, реализующие Moon
.