Creating Hashtable as final in java

JavaHashtable

Java Problem Overview


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????

Java Solutions


Solution 1 - Java

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.

Solution 2 - Java

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);    

    }

}

Solution 3 - Java

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.

Solution 4 - Java

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.

Solution 5 - Java

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)

Solution 6 - Java

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSathishView Question on Stackoverflow
Solution 1 - JavaJoeView Answer on Stackoverflow
Solution 2 - JavaVladView Answer on Stackoverflow
Solution 3 - JavaIngo KegelView Answer on Stackoverflow
Solution 4 - JavaThomasView Answer on Stackoverflow
Solution 5 - JavaJeff FosterView Answer on Stackoverflow
Solution 6 - JavaG_HView Answer on Stackoverflow