2018.7.12

ListやMapをstatic finalで読み取り専用として定義する際の注意点

通常、処理の中で変更されることがない値を定義する場合は、static finalで読み取り専用の定数として宣言しますが、ListやMapで同じようなことをしようとする際は注意が必要です。

コード

通常と同じようにstatic finalで宣言すると、以下のコードでは追加や削除などの変更ができてしまいます。


private static final List<String> list = new ArrayList<String>() {
    {
        add("a");
        add("b");
        add("c");
        add("d");
        add("e");
    }
};

private static final Map<String, String> map = new HashMap<String, String>() {
    {
        put("a", "1");
        put("b", "2");
        put("c", "3");
        put("d", "4");
        put("e", "5");
    }
};

private static void testListAdd(){
    list.add("f");              // 追加可能
    System.out.println(list);   // [a, b, c, d, e, f]
}

private static void testMapPut(){
    map.put("f", "6");          // 追加可能
    System.out.println(map);    // {f=6, d=4, e=5, b=2, c=3, a=1}
}

変更させないようにするには以下のように読み取り専用で定義します。


private static final List<String> list = Collections.unmodifiableList(new ArrayList<String>() {
    {
        add("a");
        add("b");
        add("c");
        add("d");
        add("e");
    }
});

private static final Map<String, String> map = Collections.unmodifiableMap(new HashMap<String, String>() {
    {
        put("a", "1");
        put("b", "2");
        put("c", "3");
        put("d", "4");
        put("e", "5");
    }
});

private static void testListAdd(){
    list.add("f");      // 追加NG。「java.lang.UnsupportedOperationException」が発生
}

private static void testMapPut(){
    map.put("f", "6");  // 追加NG。「java.lang.UnsupportedOperationException」が発生
}

参考リンク

Java】関連記事