在 Java 中,final 字段可以从构造函数助手中初始化吗?
我有一个最终的非静态成员:
private final HashMap<String,String> myMap;
我想使用构造函数调用的方法来初始化它。由于 myMap 是最终的,因此我的“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...
}
I have a final non-static member:
private final HashMap<String,String> myMap;
I would like to initialize it using a method called by the constructor. Since myMap is final, my "helper" method is unable to initialize it directly. Of course I have options:
I could implement the myMap initialization code directly in the constructor.
MyConstructor (String someThingNecessary)
{
myMap = new HashMap<String,String>();
myMap.put("blah","blahblah");
// etc...
// other initialization stuff unrelated to myMap
}
I could have my helper method build the HashMap, return it to the constructor, and have the constructor then assign the object to 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;
}
Method #2 is fine, however, I'm wondering if there's some way I could allow the helper method to directly manipulate myMap. Perhaps a modifier that indicates it can only be called by the constructor?
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...
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
方法#2 是您最好的选择。问题是,如果您在私有方法中进行了赋值,则无法阻止构造函数之外的类中的其他代码调用它,这会导致尝试对最终字段进行第二次赋值时出现问题。
Java 没有构造只能在构造期间调用的单独方法。
为了完整起见,我们可以制作第三个选项,在初始化时分配映射,然后让辅助方法填充它:
然后:
如果你真的想混淆,你可以使用初始化器而不是构造函数,但你应该不要这样做,所以除非你真的需要知道,否则我不会对此进行扩展。
Method #2 is your best option. The problem is that if you have an assignment in a private method there is nothing preventing other code in the class outside the constructor calling it, which would then create an issue with an attempted second assignment to the final field.
Java has no construct of a separate method that can only be called during construction.
For completeness, we can make a third option, where you assign the map at initialization and then have the helper method fill it:
And then:
And if you really want to be confusing you can use an initializer instead of a constructor, but you should not do that, so unless you really need to know, I won't expand on that.
如何实现一个初始化 HashMap 的私有构造函数,然后让主构造函数调用该私有构造函数?
例如,
您可以根据需要修改私有辅助构造函数的签名(例如,提供参数数据或使签名与任何公共构造函数不同)。
How about implementing a private constructor that initializes your HashMap, and then have your main constructor(s) call that private constructor?
For example--
You can modify the signature of the private helper constructor as needed (e.g. to provide parameter data or to make the signature distinct from any public constructors).
选项 #2 是最可重用的选项,因为您可以在所有构造函数之间共享它。这里我们需要的是 c# 的集合初始值设定项。 :)
(顺便说一句:#3 无法编译)
Option #2 is the most resuable option, because you can share it among all constructors. What we would need here, are collection initializers of c#. :)
(BTW: #3 won't compile)