问题
As we know the purpose of "final" keyword in java. While declaring a variable as final, we have to initialize the variable. like "final int a=10;" We can not change the value of "a". But if we go for HashTable its possible to add some value even declaring the HashTable as final.
Example::
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); }};
Now I am declaring the MYHASH HashTable as final. If I try to add some more elements to this, its accepting.
MYHASH.put("NEW DATA", 256);
Now the "NEW DATA" is added to the HashTable. My questions is Why its allowing to add even its declaring as final????
回答1:
Because final marks the reference, not the object. You can't make that reference point to a different hash table. But you can do anything to that object, including adding and removing things.
Your example of an int
is a primitive type, not a reference. Final means you cannot change the value of the variable. So, with an int
you cannot change the value of the variable, e.g. make the value of the int
different. With an object reference, you cannot change the value of the reference, i.e. which object it points to.
回答2:
Only the reference is final, its methods can of course be called just as for a non-final reference.
Use Collections.unmodifiableMap(map)
to make a map unmodifiable.
回答3:
You can use Collections.unmodifiableMap to get an unmodifiable wrapper over your hash table.
Example:
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:
Try and wrap your Hashtable
with an unmodifiable map using Collections.unmodifiableMap( MYHASH )
. This should throw exceptions when you try to change something in the map, i.e. add or remove entries. (Note that MYHASH
should then be of type Map<String, String>
and not Hashtable<String, String>
.)
Regarding the final
keyword: as the others already said, it means that you can't assign another Hashtable
to MYHASH
but the map itself is still mutable. To change this you have to wrap it with some immutable wrapper, like the UnmodifiableMap
mentioned above.
回答5:
As Joe said, this is because final
marks the reference not the object.
However, you can do what you want with Collections.unmodifiableMap
(see here)
回答6:
For fields and variables, using final
means they can be assigned only once. Either immediately, or at some later time (e.g. in a constructor for fields). This doesn't mean the actual instance becomes immutable. A Hashtable is a data structure that you can add entries to, regardless of how it was assigned to some variable. Only the reference is final.
来源:https://stackoverflow.com/questions/7996499/creating-hashtable-as-final-in-java