あなた自身の答えから、私はあなたがクラスOMG
にマップに格納されている実際の設定のためのキーとデフォルト値として列挙エントリを使用することをお読みください。この構成は、ファイルにも書き込む必要があります。
ここで、設計上の決定を下す必要があります。いつどの設定キーを使用できるか、デフォルト値を変更できるようにしたいのですか?プログラムはすでに(実行時に)実行されているか、プログラムが(コンパイル時に)再コンパイルされていますか?
説明は、実行時に変更できるようにすることをお勧めします。これは正しいです?また、これは本当に必要ですか?あなたの既存のコードはおそらく、新しいキーに提供されている値を使用しません。また、変更されたデフォルト値は、おそらく古いデフォルト値を使用して初期化されているため、影響を与えません。
実行時にこれらの情報を本当に変更したい場合は、列挙型を使用してそれらを格納して読み込むべきではありません。このようなプログラミングスタイルはJavaScriptなどのスクリプト言語でも機能しますが、Javaではうまく機能しません。列挙型は他のコードと同様に、実行時には変更されませんが、コンパイル時に指定する必要があります。
実行時にコードが変更されることは想定されていないため、JVMはクラスローダーの魔法をせずに単にクラスをリロードすることさえ許可しません。可能であれば、これを避けたいと考えています。詳細については、hereを参照してください。実行時にクラスをリロードすることは不可能ではありませんが、あなたが直面している問題に対して間違った解決策であることは間違いありません。
正しい解決策は何ですか?実行時に情報を本当に変更する必要があると私はまだ確信していません。これが正しい場合、コンパイル時に情報を変更するだけでよい場合は、現在の列挙型アプローチを使用することができます。ただし、クラスを名前でロードしないようにシンプルにすることができます。実装についての詳細は、以下を参照してください。
実際に実行時に情報を変更する必要がある場合は、情報をコードに保存するのではなく、ファイルに保存してください。これにより、ファイルを読み直して簡単に情報をリロードすることができます。プロパティファイルを使用することができます。これは、Javaワールドでは一般的です。hereを参照してください。より構造化されたファイル形式が必要な場合は、JSONファイルを使用できます。 Javaでは、Gsonを使用してJSONファイルを操作できます(hereを参照)。
これが私の作品:
package test;
import java.util.Arrays;
import java.util.EnumMap;
public class Test {
public static enum SETTINGS {
Setting1("OMG setting 1"), Setting2("OMG setting 2");
private String key;
@Override
public String toString() {
return "SETTINGS: " + key;
}
SETTINGS(String key) {
this.key = key;
}
}
public static class OMG<E extends Enum<E>> {
String name;
EnumMap<E, String> settings;
public OMG(String name, EnumMap<E, String> settings) {
this.name = name;
this.settings = settings;
}
public static <E extends Enum<E>> OMG<E> create(String name,
Class<E> enumClass) {
return new OMG<E>(name, new EnumMap<E, String>(enumClass));
}
}
public static void main(String[] args) {
try {
Class c = Class.forName("test.Test$SETTINGS");
// alternatively you can use:
// Class<SETTINGS> c = SETTINGS.class;
System.out.println(Arrays.toString(c.getEnumConstants()));
OMG.create("foobar", c);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
私はあなたがクラスOMG
だけでなくSETTINGS
に任意の列挙型を渡したいと仮定しました。 SETTINGS
のみにする必要がある場合は、SETTINGS
をコード内で直接使用することもできます。これがSETTINGS
列挙型をOMG
クラスから移動した理由です。
次に、汎用タイプのパラメータE
をクラスOMG
に追加しました。したがって、OMG
はSETTINGS
に直接依存しません。簡単な初期化を可能にするために、static factoryメソッドをOMG
に追加しました。このメソッドはジェネリック型パラメータE
も使用しています。 E
と一致する名前とクラスオブジェクトを受信するだけです。 Javaでは、ジェネリック型のパラメータを直接反映させることができないため、クラスオブジェクトが必要です。
また、EnumMap
は、キーが列挙型の場合に最適化されたマップ実装であるため、をEnumMap
に置き換えました。
最後に、OMG
クラスの初期化:リフレクションを使用して、クラス名からクラスオブジェクトを実際に作成する必要がある場合は、そのコードをそのまま使用できます。これにより、警告が生成されることに注意してください。しかし、ほとんどの場合、コメント行のコードのように、クラスオブジェクトを直接使用することが必要です。この2番目の方法を使用すると、警告が表示されず、try-catchブロックを省略することもできます。
本当にあなたはenum名で作業する必要がありますか?なぜあなたは 'HashMap'を作成できないのですか?また、 'OMG'クラスは任意の列挙型で動作するか、単に' SETTINGS'列挙型で動作する必要がありますか? –
実際にOMGクラスには複数の列挙型があり、複数の辞書を渡す必要があります – mp3por
問題は解決しましたか?そうでない場合は、コード例と問題の説明を投稿してください。そうであれば、最も役に立つ回答を受け入れることでこれを示してください。 –