为什么私有静态最终列表/集/地图不可修改?

Kon*_*tin 9 java collections constants map immutability

我刚读了一些由经验丰富的程序员编写的代码,我发现了以下内容:

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);
    }

    // ...

}
Run Code Online (Sandbox Code Playgroud)

如您所见,这是一个用于格式化日志输出的类.然而,引起我注意的是静态初始化程序块中的代码:PREFIXES = Collections.unmodifiableMap(prefixes);.

为什么要PREFIXES制作一个不可修改的地图?它是一个私有常量,因此不存在修改该类之外的数据的风​​险.这样做是为了让常数的不变性成为一种完整感吗?

就个人而言,我会直接初始化PREFIXES为a HashMap,然后直接初始化put键值对,而不创建虚拟占位符映射或使字段成为不可变映射.我在这里错过了什么吗?

Lou*_*man 9

如果你不小心return PREFIXES从一个方法,突然任何其他代码可以修改它.当你在将来凌晨3点修改代码时,使常量真正不变是可以防止你自己的愚蠢.


Pet*_*ker 9

通过使列表不可修改,作者记录了他的假设,即值永远不会改变.谁可能在以后编辑该类不仅可以看到该假设,而且还会被提醒以防它被破坏.

这只有在采取长期观点时才有意义.它降低了因维护而产生新问题的风险.我喜欢这种编程风格,因为即使在我自己的课程中,我也倾向于破坏它.有一天,你可能会进行快速修复而忘记最初做出的假设并且与正确性相关.锁定代码的次数越多越好.

  • _"有一天,你可能会进行快速修复而忘记最初做出的假设并且与正确性相关."_哦,小伙子,我确切地知道你的意思. (2认同)