質問

クラス内に保持されているマップで実行できる静的メソッドのクラスがあり、クラスが呼び出されたときにマップを設定したいと思います。私はプライベートコントラクトを使用してみましたが、呼ばれていません。私のコードの関連部分は次のとおりです。

public class MyClass
{
    private static final String KEYS = "ABC";
    private static final String[] DATA = {"AAA", "BBB", "CCC"};
    private static HashMap<Character, String> myMap;

    private MyClass() {
        System.out.println("Running constructor");
        populateMyMap();
    }

    private static void populateMyMap() {
        myMap = new HashMap<Character, String>();
        for (int i=0; i < KEYS.length; i++) {
            myMap.put(KEYS.charAt(i), DATA[i]);
        }
    }

    //various static methods
}

プライベートコンストラクターはここで使用するのに正しいものですか?もしそうなら、私は何が間違っていますか?

これが重複している場合は申し訳ありません。答えを探してみましたが、何を探すべきかわかりません!

役に立ちましたか?

解決

静的初期イザーブロックは、他のいくつかの回答で言及されています。しかし、実際には、私は次のイディオムを野生でより頻繁に見つけます:

public class MyClass
{
    private static HashMap<Character, String> myMap = createMyMap();

    private static HashMap<Character, String> createMyMap() {
        HashMap<Character, String> myTmpMap = new HashMap<Character, String>();
        for (int i=0; i < KEYS.length; i++) {
            myTmpMap.put(KEYS.charAt(i), DATA[i]);
        }
        return myTmpMap;
    }
}

他のヒント

いいえ、プライベートコンストラクターはあなたが望むものではありません。コンストラクターが初期化されます 実例 あなたのクラスの(あなたが電話するとき new MyClass())、しかし、静的状態はインスタンスに属していないため、コンストラクターから初期化するべきではありません。クラスが最初にロードされたときに起こりたいという初期化 static クラスレベルに配置されたブロック。

static {
   populateMyMap();
}

ただし、静的(グローバル)状態を使用しないでください。 Static Stateは、システムをテストするのが法外に困難になります。インスタンス状態(たとえば、クラスの負荷ごとに1つのコピーがあります)よりも微妙です。通常、スレッドを安全にするのは難しいです。

マップを作成することを検討してください インスタンスメンバー 代わりにあなたのクラスの。

静的イニシャルを使用します:

public class MyClass
{
    static {
    //init
    }
}

これを達成するには2つの方法があります。 1つは、「populatemymap」メソッドを静的イニシャルイザー(またはAHによって提案されたアプローチ)にすることです。次に、最初の静的コールの前に実行されることが保証されます。これは通常、Populatemymapを実行するコストが気付かないほど小さいか、アプリケーションが実行されるたびにクラスの機能を使用する場合に仮定します。

別のアプローチは、「populatemymap」を実行するとかなりの時間がかかる場合に使用するものであり、アプリの一部の実行に機能を使用しないか、データまでPopulatemymapの実行を延期したい場合があります。スタートアップ時間を不必要に増やさないようにするために必要です。

2番目のアプローチが必要な場合は、構造を切り替えて、静的な方法ではなくシングルトンを使用する必要があります。メソッド(およびデータ)を非静的にし、それらの各ユーザーにメソッドを呼び出す前にSingletonインスタンスを取得します。 (プライベート)コンストラクターで「Populatemymap」と呼ばれています。はい、私は知っています、シングルトンは評判が悪く、人々は常に「彼らは変装したグローバルな方法であるため、それらを避けてください」と言いますが、静的な方法は単なるグローバルな方法です。あなたは何も失っていません。そして、このようにして、あなたはあなたがする必要があるまで(または必要でない限り)populatemymapを実行する費用を支払いません。

警告:データ構造が不変でない場合、つまり、初期化された後に変更できます。おそらく、これらの構造のいずれかを使用してはいけません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top