Создание Hashtable как финала в Java - PullRequest
35 голосов
/ 03 ноября 2011

Как мы знаем цель «окончательного» ключевого слова в Java. Объявляя переменную как final, мы должны инициализировать переменную. как " final int a = 10;" Мы не можем изменить значение «а». Но если мы перейдем к HashTable, можно добавить некоторое значение, даже объявив HashTable как окончательное.

Пример ::

 private static final Hashtable<String,Integer> MYHASH = new Hashtable<String,Integer>() 
{{     put("foo",      1);     
       put("bar",      256);     
       put("data",     3);     
       put("moredata", 27);     
       put("hello",    32);     
       put("world",    65536);  }}; 

Теперь я объявляю MYHASH HashTable финальным. Если я попытаюсь добавить к этому еще несколько элементов, он будет принят.

MYHASH.put("NEW DATA",      256);

Теперь «НОВЫЕ ДАННЫЕ» добавляются в HashTable. Мои вопросы: почему его разрешают добавить даже объявление в качестве окончательного ????

Ответы [ 6 ]

75 голосов
/ 03 ноября 2011

Потому что final помечает ссылку, а не объект. Вы не можете сделать эту ссылку на другую хеш-таблицу. Но вы можете делать с этим все что угодно, включая добавление и удаление объектов.

Ваш пример int является примитивным типом, а не ссылкой. Окончательный означает, что вы не можете изменить значение переменной. Таким образом, с int вы не можете изменить значение переменной, например, сделать значение int другим. Со ссылкой на объект вы не можете изменить значение ссылки, то есть на какой объект он указывает.

13 голосов
/ 03 ноября 2011

Только ссылка является окончательной, ее методы, конечно, можно вызывать так же, как и для неконечной ссылки.

Используйте Collections.unmodifiableMap(map), чтобы сделать карту не изменяемой.

12 голосов
/ 03 ноября 2011

Вы можете использовать Collections.unmodifiableMap, чтобы получить неизменяемую оболочку для вашего хеш-таблицы.

Пример:

import java.util.*;
class Test{

    public static final Map<String,Integer> MYHASH;
    static{
        Hashtable<String,Integer> tmp = 
            new Hashtable<String,Integer>();
        tmp.put("A",65);
        tmp.put("C",67);
        MYHASH = Collections.unmodifiableMap(tmp);
    }

    public static void main(String[] args){

        System.out.println(MYHASH.get("A"));

        //this will throw
        //java.lang.UnsupportedOperationException
        MYHASH.put("B",66);    

    }

}
6 голосов
/ 03 ноября 2011

Попробуйте обернуть Hashtable неизменяемой картой, используя Collections.unmodifiableMap( MYHASH ).Это должно вызывать исключения, когда вы пытаетесь что-то изменить на карте, то есть добавлять или удалять записи.(Обратите внимание, что MYHASH должен иметь тип Map<String, String>, а не Hashtable<String, String>.)

Относительно ключевого слова final: как уже говорили другие, это означает, что вы не можете назначить другое *От 1009 * до MYHASH, но сама карта все еще изменчива.Чтобы изменить это, вы должны обернуть его какой-нибудь неизменяемой оболочкой, как UnmodifiableMap, упомянутый выше.

4 голосов
/ 03 ноября 2011

Как сказал Джо, это потому, что final отмечает ссылку, а не объект.

Однако вы можете делать все, что вы хотите, с помощью Collections.unmodifiableMap (см. здесь )

0 голосов
/ 03 ноября 2011

Для полей и переменных использование final означает, что они могут быть назначены только один раз.Либо сразу, либо в более позднее время (например, в конструкторе для полей).Это не означает, что фактический экземпляр становится неизменным.Hashtable - это структура данных, в которую можно добавлять записи независимо от того, как они были назначены какой-либо переменной.Только ссылка является окончательной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...