44

我有一个最终的非静态成员:

private final HashMap<String,String> myMap;

我想使用构造函数调用的方法对其进行初始化。由于 myMap 是最终的,我的“帮助”方法无法直接初始化它。当然我有选择:

我可以直接在构造函数中实现 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 是您的最佳选择。问题是,如果您在私有方法中进行了赋值,则没有什么可以阻止在构造函数调用它之外的类中的其他代码,这将导致尝试对 final 字段进行第二次赋值的问题。

Java 没有构造只能在构造期间调用的单独方法。

为了完整起见,我们可以做第三个选项,在初始化时分配映射,然后让辅助方法填充它:

 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 回答