Создание 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 добавляется "НОВЫЕ ДАННЫЕ".
Мои вопросы: почему он позволяет добавить даже объявление в качестве окончательного?
Ответы
Ответ 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 - это структура данных, к которой вы можете добавлять записи, независимо от того, как она была назначена некоторой переменной. Только ссылка является окончательной.