44

私には最後の非静的メンバーがいます:

private final HashMap<String,String> myMap;

コンストラクターによって呼び出されるメソッドを使用して初期化したいのですが。myMapはfinalであるため、「helper」メソッドはそれを直接初期化できません。もちろん、私には選択肢があります:

myMap初期化コードをコンストラクターに直接実装できます。

MyConstructor (String someThingNecessary)
{
    myMap = new HashMap<String,String>();

    myMap.put("blah","blahblah");
    // etc...

    // other initialization stuff unrelated to myMap
}

ヘルパーメソッドでHashMapを作成し、それをコンストラクターに返し、コンストラクターでオブジェクトをmyMapに割り当てることができます。

MyConstructor (String someThingNecessary)
{
    myMap = InitializeMyMap(someThingNecessary);

    // other initialization stuff unrelated to myMap
}

private HashMap<String,String> InitializeMyMap(String someThingNecessary)
{
    HashMap<String,String> initializedMap = new HashMap<String,String>();

    initializedMap.put("blah","blahblah");
    // etc...

    return initializedMap;
}

方法2は問題ありませんが、ヘルパーメソッドがmyMapを直接操作できるようにする方法があるかどうか疑問に思っています。おそらく、コンストラクターによってのみ呼び出すことができることを示す修飾子ですか?

MyConstructor (String someThingNecessary)
{
    InitializeMyMap(someThingNecessary);

    // other initialization stuff unrelated to myMap
}


// helper doesn't work since it can't modify a final member
private void InitializeMyMap(String someThingNecessary)
{
    myMap = new HashMap<String,String>();

    myMap.put("blah","blahblah");
    // etc...
}
4

3 に答える 3

17

方法2が最善の選択肢です。問題は、プライベートメソッドに割り当てがある場合、コンストラクターの外部にあるクラス内の他のコードがそれを呼び出すことを妨げるものがないことです。これにより、最後のフィールドへの2番目の割り当てが試行されると問題が発生します。

Javaには、構築中にのみ呼び出すことができる別個のメソッドの構築はありません。

完全を期すために、3番目のオプションを作成できます。このオプションでは、初期化時にマップを割り当ててから、ヘルパーメソッドでマップを埋めます。

 private final HashMap<String, String> myMap = new HashMap<String, String();

その後:

 MyConstructor (String someThingNecessary)
 {
    initializeMyMap(someThingNecessary);

    // other initialization stuff unrelated to myMap
 }


 // helper doesn't work since it can't modify a final member
 private void initializeMyMap(String someThingNecessary)
 {

     myMap.clear();
    myMap.put("blah","blahblah");
    // etc...
  }

また、本当に混乱させたい場合は、コンストラクターの代わりに初期化子を使用できますが、そうすべきではありません。したがって、本当に知る必要がない限り、これについては詳しく説明しません。

于 2010-05-18T17:36:58.087 に答える
14

HashMapを初期化するプライベートコンストラクターを実装してから、メインコンストラクターにそのプライベートコンストラクターを呼び出させるのはどうですか?

例えば ​​-

// Helper function to initialize final HashMap.
private MyConstructor()
{
    myMap = new HashMap<String,String>();
    myMap.put("blah","blah");
}

MyConstructor (String someThingNecessary)
{
    // Initialize the HashMap.
    this();
    // Other initialization code can follow.
}

必要に応じて、プライベートヘルパーコンストラクターの署名を変更できます(たとえば、パラメーターデータを提供したり、署名をパブリックコンストラクターと区別したりするため)。

于 2011-07-04T20:03:23.587 に答える
1

オプション#2は、すべてのコンストラクター間で共有できるため、最も再利用可能なオプションです。ここで必要になるのは、c#のコレクション初期化子です。:)

(ところで:#3はコンパイルされません)

于 2010-05-18T17:42:06.920 に答える