我有以下界面:
public interface Moon {
// Enums can not extend any class in Java,
// thus I am implementing an interface
double getMass();
double getDiameter();
}
Run Code Online (Sandbox Code Playgroud)
这是由我的枚举实现的(我省略了构造函数和方法的实现)
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
}
Run Code Online (Sandbox Code Playgroud)
对于其他行星也有类似的枚举:
public enum Mars implements Moon {
PHOBOS(22.2, 1.08),
DEIMOS(12.6, 2);
private double Diameter;
private double Mass;
// constructor and methods implementation
}
Run Code Online (Sandbox Code Playgroud)
问题
有两个字符串:
String planetName = "Mars";
String moonName = "PHOBOS";
Run Code Online (Sandbox Code Playgroud)
如何以智能方式获取特定枚举?
在只有一个枚举类的情况下,这是该valueOf方法的一种简单使用,但如何检查实现特定接口的所有枚举?
Moon something = <??planetName??>.valueOf(moonName);
Run Code Online (Sandbox Code Playgroud)
您可以使用行星名称到相关枚举类型的映射,并使用它来执行查找。
例如,使用地图(肯定有替代方法):
Map<String, Class<? extends Enum>> planetMoonTypes = new HashMap<>();
planetMoonTypes.put("Saturn", Saturn.class);
planetMoonTypes.put("Mars", Mars.class);
Run Code Online (Sandbox Code Playgroud)
使用这样的映射,您可以"PHOBOS"使用以下方式查找值:
Moon phobos = (Moon) Enum.valueOf(planetMoonTypes.get("Mars"), "PHOBOS");
Run Code Online (Sandbox Code Playgroud)
上面会返回Mars.PHOBOS
编辑:关于添加非 Moon 枚举的能力。您可以封装地图并强制执行正确的边界。例如,以下使用了一种方法:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
同样,此解决方案不能完全类型安全,因为存在多个枚举子类型(如您所见,原始类型Enum位于实例字段的类型中)。但如果这是正确封装的,并且您的代码不使用此类之外的原始类型,则可以确保仅Moon添加枚举类型实现。