2011-11-03 20 views
26

Como sabemos el propósito de la palabra clave "final" en java. Mientras declaramos una variable como final, tenemos que inicializar la variable. como "final int a = 10;" No podemos cambiar el valor de "a". Pero si optamos por HashTable, es posible agregar algún valor, incluso declarando HashTable como final.Crear Hashtable como final en java

Ejemplo ::

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

Ahora estoy declarando la MYHASH HashTable como definitiva. Si trato de agregar algunos elementos más a esto, es aceptable.

MYHASH.put("NEW DATA",  256); 

Ahora se agrega "NEW DATA" a la HashTable. Mi pregunta es ¿Por qué está permitiendo agregar incluso su declaración como final ????

+0

Nota si el contenido del mapa eran mutables ('' java.util.Date' o java.awt.Point', por ejemplo) entonces sigue siendo mutables. –

Respuesta

63

Porque el final marca la referencia, no el objeto. No puede convertir ese punto de referencia en una tabla hash diferente. Pero puede hacer cualquier cosa con ese objeto, incluyendo agregar y eliminar cosas.

Su ejemplo de int es un tipo primitivo, no una referencia. Final significa que no puede cambiar el valor de la variable. Por lo tanto, con un int no puede cambiar el valor de la variable, p. hacer que el valor de int sea diferente. Con una referencia de objeto, no puede cambiar el valor de la referencia, es decir, a qué objeto apunta.

0

Para campos y variables, usar final significa que se pueden asignar solo una vez. O inmediatamente o en algún momento posterior (por ejemplo, en un constructor de campos). Esto no significa que la instancia real se vuelva inmutable. Una Hashtable es una estructura de datos a la que puede agregar entradas, independientemente de cómo se haya asignado a alguna variable. Solo la referencia es definitiva.

6

Pruebe y ajuste su Hashtable con un mapa no modificable usando Collections.unmodifiableMap(MYHASH ). Esto debería arrojar excepciones cuando intente cambiar algo en el mapa, es decir, agregar o quitar entradas. (Tenga en cuenta que MYHASH debería entonces ser de tipo Map<String, String> y no Hashtable<String, String>.)

En cuanto a la palabra clave final: como los demás ya se ha dicho, significa que no se puede asignar otro Hashtable a MYHASH pero el mapa en sí es todavía mutables. Para cambiar esto, debe envolverlo con un envoltorio inmutable, como el UnmodifiableMap mencionado anteriormente.

12

Solo la referencia es definitiva; por supuesto, sus métodos pueden llamarse igual que para una referencia no final.

Usa Collections.unmodifiableMap(map) para hacer un mapa no modificable.

4

Como dijo Joe, esto se debe a que final marca la referencia, no el objeto.

Sin embargo, puede hacer lo que quiera con Collections.unmodifiableMap (ver here)

8

Puede utilizar Collections.unmodifiableMap para obtener una envoltura no modificable por encima de su tabla hash.

Ejemplo:

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

    } 

} 
+1

Obtiene mi +1 porque claramente no está manteniendo la versión mutable del mapa a punto de mutar inadvertidamente. Hubiera preferido mantener el inmóvil estático 'privado'. También no tiene sentido usar 'Hashtable'. –

+0

¡Gracias! Fui con 'Hashtable' por coherencia con la pregunta, pero no me di cuenta de lo 'privado'. – Vlad

+0

Gracias también resolvió mi problema. – bean