После назначения карты в ImmutableMap, как остановить или ограничить переназначение другой карты - PullRequest
2 голосов
/ 10 ноября 2019

Я объявил ImmutableMap как

public static ImmutableMap<String, String> mapImmutable;

Назначил карту для этой переменной

mapImmutable= ImmutableMap.copyOf(map2);

Теперь, если я назначу другую карту этой переменной 'mapImmutable'. Он не будет генерировать никаких исключений и обновит значения.

mapImmutable=ImmutableMap.copyOf(map3);

открытый класс UnmodifiedMap {

public static ImmutableMap<String, String> mapImmutable;

public static void main(String[] args) {
    Map<String,String> map2=new HashMap<String,String>();

    map2.put("name", "mark");
    mapImmutable= ImmutableMap.copyOf(map2);
    System.out.println(mapImmutable);

    Map<String,String> map3=new HashMap<String,String>();

    map3.put("Country", "USA");
    map3.put("name", "Joy");

            mapImmutable=ImmutableMap.copyOf(map3);\\It should throw an exception while reassign.
    System.out.println(mapImmutable);}}

Результат консоли -: {name = mark} {Country = USA}

Должен выдать исключение при переназначении.

Ответы [ 2 ]

3 голосов
/ 10 ноября 2019

Вы должны различать неизменность Map и неизменность поля mapImmutable.

ImmutableMap, как следует из названия, является неизменным, однако в вашем коде поле, указывающее на карту, является просто регулярным полем. Поэтому его можно переназначить, чтобы он указывал на другую карту. Если вы хотите, чтобы поле было неизменным, просто пометьте его final.

0 голосов
/ 10 ноября 2019

Здесь:

mapImmutable = ImmutableMap.copyOf(map3);

Вы фактически не меняете содержимое карты, к которой относится поле mapImmutable. Вы заставляете mapImmutable ссылаться на совершенно другую карту!

ImmutableMap неизменность не означает, что вы можете сбросить переменную этого типа. Это только означает, что его экземпляры не изменятся. например, вы не можете добавлять новые элементы на карту или удалять элементы с нее. В приведенной выше строке вы не изменяете экземпляры ImmutableMap, вы создаете новый экземпляр ImmutableMap, вызывая copyOf и присваивая его mapImmutable. Карта, на которую ссылался mapImmutable, не изменяется, а просто потерян .

Если вы хотите запретить сброс поля, объявите его как final и установите его встатический конструктор:

public final static ImmutableMap<String, String> mapImmutable;

static {
    Map<String,String> map2=new HashMap<String,String>();

    map2.put("name", "mark");
    mapImmutable= ImmutableMap.copyOf(map2);
    System.out.println(mapImmutable);

    Map<String,String> map3=new HashMap<String,String>();

    map3.put("Country", "USA");
    map3.put("name", "Joy");

            mapImmutable=ImmutableMap.copyOf(map3); // now we have an error!
    System.out.println(mapImmutable);}
}

Также обратите внимание, что final только предотвращает сброс поля / переменной, но не препятствует изменению объекта. Если у вас есть final HashMap, вы все равно можете добавить к нему KVP.

...