Reputation: 1056
I have this assignment to a static variable that reads data off a file:
public static final Map<String, Integer> MY_DATA_RESOURCE;
static {
MY_DATA_RESOURCE = parseAndTransformFile();
}
I want this variable to be publicly accessible to all classes and I want to initialize it with this method call. Doing this triggers a Sonar complaint "Mutable fields should not be "public static" though.
I have that parseAndTransform method which I do not want to call directly multiple times and trigger a read each time and I also want to avoid adding a getter method which is basically adding a third layer to data access.
Do I have any other options here?
Upvotes: 1
Views: 3765
Reputation: 6969
You could use Guava's immutable maps:
public static final ImmutableMap<String, Integer> MY_DATA_RESOURCE =
ImmutableMap.copyOf(yourMethodCall());
You also could use a static method, not field:
private static final Map<String, Integer> MY_DATA_RESOURCE;
static {
MY_DATA_RESOURCE = parseAndTransformFile();
}
public static Map<String, Integer> myDataResource() {
return Collections.unmodifiableMap(MY_DATA_RESOURCE);
}
with this approach, you could also eventually decide to parse and transform the file lazily (when someone inquired about its contents) rather than in the static {}
block.
Upvotes: 1
Reputation: 13581
However your field is declared as final
, map itself is not immutable and you can still put()
some items to it (unless you are using some Collections.unmodifiableMap()
- but anyway you don't know this by interface) and that's why Sonar is complaining
Try to wrap the Map
in some immutable class implementation and change the type of the field to this class. This has this additional advantage, that if in the future you will decide that you need to add some additional meta-data about file (like creation time) instead of sculpting in the Map
structure you can easily add a field to your own mapper class
Upvotes: 1