I just read some code written by a more experienced programmer, and I came across the following:
public class ConsoleFormatter extends Formatter {
private static final Map<Level, String> PREFIXES;
static {
Map<Level, String> prefixes = new HashMap<Level, String>();
prefixes.put(Level.CONFIG, "[config]");
prefixes.put(Level.FINE, "[debug]");
prefixes.put(Level.FINER, "[debug]");
prefixes.put(Level.FINEST, "[trace]");
prefixes.put(Level.INFO, "[info]");
prefixes.put(Level.SEVERE, "[error]");
prefixes.put(Level.WARNING, "[warning]");
PREFIXES = Collections.unmodifiableMap(prefixes);
}
// ...
}
As you can see, this is a class used for formatting log output. What caught my eye, however, was the code in the static initializer block: PREFIXES = Collections.unmodifiableMap(prefixes);.
Why was PREFIXES made an unmodifiable map? It’s a private constant, so there’s no risk of modifying the data outside of that class. Was it done to give the constant’s immutability a sense of completeness?
Personally, I would’ve directly initialized PREFIXES as a HashMap and then put the key–value pairs in directly, without creating a dummy, placeholder map or making the field an immutable map. Am I missing something here?
By making the list unmodifiable the author documented his assumption that the values will never change. Whoever might edit that class later on can not only see that assumption, but will also be reminded in case it is ever broken.
This makes sense only when taking the longer-term view. It reduces the risk of new problems arising through maintenance. I like to do this style of programming, because I tend to break stuff even in my own classes. One day you might go in for a quick fix and you forget about an assumption that was made originally and is relevant for correctness. The more you can lock the code down, the better.