matandked:
私は、次のインタフェースを持っています:
public interface Moon {
// Enums can not extend any class in Java,
// thus I am implementing an interface
double getMass();
double getDiameter();
}
私の列挙型で実装されている(私は、コンストラクタとメソッドの実装を省略)
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
}
同様に他の惑星の列挙型の値:
public enum Mars implements Moon {
PHOBOS(22.2, 1.08),
DEIMOS(12.6, 2);
private double Diameter;
private double Mass;
// constructor and methods implementation
}
質問
2つの文字列を持ちます:
String planetName = "Mars";
String moonName = "PHOBOS";
どのように私はスマートな方法で特定の列挙型を得ることができますか?
一つだけ列挙型クラスの場合、それは簡単な使用であるvalueOf
方法が、どのように私は、特定のインターフェイスを実装するすべての列挙型を確認することができますか?
Moon something = <??planetName??>.valueOf(moonName);
ernest_k:
あなたは、関連する列挙型に惑星名のマッピングを使用し、ルックアップを実行するためにそれを使用することができます。
例えば、マップを(確実に別のアプローチがある)を使用して:
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
EDIT:非ムーン列挙型を追加する機能について。あなたは、マップをカプセル化し、適切な境界を強制することができます。例えば、以下はそのための方法を使用しています。
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
型がインスタンスフィールドのタイプです)。これが適切にカプセル化され、あなたのコードは、このクラスの外では、生の型を使用しない場合でも、あなたは実装のみ列挙型があることを保証することができますMoon
追加されます。