Подтвердить что ты не робот

Создание Hashtable в качестве final в java

Как мы знаем цель "окончательного" ключевого слова в java. Объявляя переменную как final, мы должны инициализировать переменную. например " final int a = 10;"  Мы не можем изменить значение "a". Но если мы перейдем к 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 добавляется "НОВЫЕ ДАННЫЕ". Мои вопросы: почему он позволяет добавить даже объявление в качестве окончательного?

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

Ответ 3

Вы можете использовать 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);    

    }

}

Ответ 4

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

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

Ответ 5

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

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

Ответ 6

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