在Java中,可以从构造函数助手初始化最后一个字段吗?

在Java中,可以从构造函数助手初始化最后一个字段吗?,java,constructor,initialization,final,Java,Constructor,Initialization,Final,我有最后一个非静态成员: private final HashMap<String,String> myMap; private final HashMap myMap; 我想使用构造函数调用的方法初始化它。因为myMap是最终的,所以我的“helper”方法无法直接初始化它。我当然有选择: 我可以直接在构造函数中实现myMap初始化代码 MyConstructor (String someThingNecessary) { myMap = new HashMap<

我有最后一个非静态成员:

private final HashMap<String,String> myMap;
private final HashMap myMap;
我想使用构造函数调用的方法初始化它。因为myMap是最终的,所以我的“helper”方法无法直接初始化它。我当然有选择:

我可以直接在构造函数中实现myMap初始化代码

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

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

    // other initialization stuff unrelated to myMap
}
MyConstructor(需要字符串)
{
myMap=newhashmap();
myMap.put(“废话”、“废话”);
//等等。。。
//其他与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;
}
MyConstructor(需要字符串)
{
myMap=初始化映射(一些必要的东西);
//其他与myMap无关的初始化内容
}
私有HashMap InitializeMap(字符串SomethingRequired)
{
HashMap initializedMap=新HashMap();
缩写为map.put(“废话”、“废话”);
//等等。。。
返回初始化的地图;
}
方法#2很好,但是,我想知道是否有某种方法可以让helper方法直接操作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...
}
MyConstructor(需要字符串)
{
初始化映射(必要时);
//其他与myMap无关的初始化内容
}
//助手无法工作,因为它无法修改最终成员
private void InitializeMap(字符串something必需)
{
myMap=newhashmap();
myMap.put(“废话”、“废话”);
//等等。。。
}
方法2是您的最佳选择。问题是,如果您在私有方法中有一个赋值,那么没有任何东西可以阻止类中调用它的构造函数之外的其他代码,这将创建一个问题,试图对最终字段进行第二次赋值

Java没有单独的方法构造,只能在构造过程中调用

为了完整性,我们可以做第三个选项,在初始化时指定映射,然后让helper方法填充它:

 private final HashMap<String, String> myMap = new HashMap<String, String();
如果你真的想让人困惑,你可以使用初始值设定项而不是构造函数,但你不应该这样做,所以除非你真的需要知道,否则我不会详细说明。选项2是最容易恢复的选项,因为你可以在所有构造函数中共享它。在这里,我们需要的是c的集合初始值设定项:)


(顺便说一句:#3不会编译)

如何实现一个私有构造函数来初始化HashMap,然后让主构造函数调用该私有构造函数

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...
}
比如说--

//用于初始化最终HashMap的Helper函数。
私有MyConstructor()
{
myMap=newhashmap();
myMap.put(“废话”、“废话”);
}
MyConstructor(需要字符串)
{
//初始化HashMap。
这个();
//其他初始化代码也可以遵循。
}

您可以根据需要修改私人助手构造函数的签名(例如,提供参数数据或使签名不同于任何公共构造函数)。

您知道回答您问题的人会怎么做吗?是的,他们将通过打开Eclipse并复制粘贴您的代码来尝试它!:)@西蒙:我的问题是,我要求一个替代我所尝试的方法。我想知道是否有比我更了解该语言的人可以指导我找到我不知道的关键字或范例。答案是否定的。来源:Java语言规范8.3.1.2;)。。。NP但我就是这么做的西蒙,我想我不知道你在说什么。我想你可能是在暗示我可以通过在Eclipse中试用我的代码来回答我自己的问题。它被称为构造函数;-)@Johannes不,他的意思是没有子构造函数的指定,允许在只能从构造函数调用方法的条件下分配最终变量。@Yishai。谢谢你的选择。另外,关于初始值设定项,我认为它无论如何都不会起作用,因为HashMap的内容实际上取决于给构造函数的参数。也许我是很密集的,但是我想不出一个理由,当它声明为Yishai建议的时,不初始化它,然后从帮助器中填充它。也许csj可以详细说明?@Stephan P据我所知,Java初始化器在对象实例化时不能提供任何参数。这与构造函数不同,后者容易接受参数,并且可以利用参数进行初始化。由于HashMap的内容取决于构造函数参数,我看不到任何使用初始值设定项的方法-在本答案的最后一句中,Yishai顺便提到了这一点。谢谢你的帮助Simon。我一开始就知道#3不会编译。我希望有一种方法可以通过保证helper只能从构造函数调用来使其合法化。这似乎是不可能的。我认为这个解决方案正是@Joey在上面提到的,他说,“实际上,Java有。它被称为构造函数”,以回应Yishai的评论,“Java没有单独的方法构造,只能在构造过程中调用。”我有点喜欢这个想法。不幸的是,它阻止我给方法一个合理的名称(比如InitializeMap)来表示它正在初始化的内容。感谢您发布到一个旧问题。我总是喜欢新的想法,或者对旧想法的澄清。谢谢,@csj。我一直在寻找同一个问题的答案,并想到了这一点。对于我同时初始化几个最终字段的用例,前面提出的方法都不能很好地工作。至于名字,是的,可能更好。但至少它与构造函数初始化某些东西是一致的。:)我是Java新手,如果有更好的解决方案,我不会感到惊讶。这是一个很好的答案。我有很多
// 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.
}