我们知道java中“final”关键字的用途。在将变量声明为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);
现在,“NEW DATA”被添加到HashTable中。 我的问题是为什么它允许甚至将其声明添加为最终的????
答案 0 :(得分:72)
因为final标记引用,而不是对象。您不能将该引用指向另一个哈希表。但是你可以对这个对象做任何事情,包括添加和删除东西。
int
的示例是基本类型,而不是引用。最终意味着您无法更改变量的值。因此,使用int
,您无法更改变量的值,例如使int
的值不同。使用对象引用时,不能更改引用的值,即它指向的对象。
答案 1 :(得分:12)
只有参考是最终的,其方法当然可以被称为非最终参考。
使用Collections.unmodifiableMap(map)
使地图无法修改。
答案 2 :(得分:10)
您可以使用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);
}
}
答案 3 :(得分:6)
使用Hashtable
尝试使用不可修改的地图包裹Collections.unmodifiableMap( MYHASH )
。当您尝试更改地图中的某些内容(即添加或删除条目)时,这应该抛出异常。 (请注意,MYHASH
应该是Map<String, String>
类型,而不是Hashtable<String, String>
。)
关于final
关键字:正如其他人已经说过的那样,这意味着您无法将另一个Hashtable
分配给MYHASH
,但地图本身仍然是可变的。要改变它,你必须用一些不可变的包装器包装它,就像上面提到的UnmodifiableMap
一样。
答案 4 :(得分:4)
正如Joe所说,这是因为final
标记了引用而不是对象。
但是,您可以使用Collections.unmodifiableMap
(请参阅here)
答案 5 :(得分:0)
对于字段和变量,使用final
表示只能分配一次。立即或稍后(例如在字段的构造函数中)。这并不意味着实际的实例变得不可变。 Hashtable是一种可以添加条目的数据结构,无论它如何分配给某个变量。只有参考是最终的。