Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Java, can a final field be initialized from a constructor helper?

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... } 
like image 341
csj Avatar asked May 18 '10 17:05

csj


People also ask

Can you initialize a final variable in a constructor Java?

A blank final variable can be initialized inside an instance-initializer block or inside the constructor. If you have more than one constructor in your class then it must be initialized in all of them, otherwise, a compile-time error will be thrown.

Can final field be set in constructor?

final means the variable can only be assigned once (in the constructor).

How do you initialize a field in a constructor in Java?

The way to initialize class fields is with something called a static initializer. A static initializer is the keyword static followed by code in curly braces. You declare a class field much as you would declare a local variable.

Can you initialize a final field in another method?

You can only initialize a final variable once.


1 Answers

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:

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

And then:

 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...   } 

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.

like image 107
Yishai Avatar answered Sep 23 '22 17:09

Yishai