2011-01-20 37 views
14

Tengo una pregunta porque me estoy poniendo un poco confundido (o tal vez no estoy notando algo obvio). Digamos que tengo algo de código fuente que contiene una gran cantidad de clases que contienen un gran número de campos estáticos definidos como éste:@SuppressWarnings ("serial")

public final class ConverterTYPE { 
    private final static HashMap<String, Byte> STRING_MAP = new HashMap<String, Byte>() { 
     { 
      put("A", new Byte((byte)12)); 
      put("B", new Byte((byte)13)); 
     } 
    }; 

} 

Como todos sabemos, los campos estáticos no van a ser serializado.

Sin embargo, Java (y Eclipse) se queja de que "La clase serializable no declara un campo estático final serialVersionUID de tipo long". ¿Por qué no se dan cuenta de que la estática no va a ser serializada?

Y la siguiente pregunta: ¿sería una solución correcta para este problema usar @SuppressWarnings("serial") para deshacerse de todas esas advertencias?

EDIT:

Ninguno de mis clases implementa la interfaz Serializable (o ninguno de sus superclases). Y Eclipse apunta al HashMap<String, Byte> con sus advertencias. ¿Por qué no detecta que es un campo estático?

+2

Para que lo sepa, HashMap implementa la interfaz Serializable. Dado que está extendiendo HashMap a una clase anónima, esa clase anónima suya también implementa Serializable. – Numeron

+1

Fuera de tema: https: //blog.jooq.org/2014/12/08/dont-be-clever-the-double-curly-braces-anti-pattern/ –

Respuesta

20

¡El hecho de que ese campo no se serialice no significa que lo que hace referencia nunca será serializado! Alguien/cosa más podría obtener una referencia a ese mapa e intentar serializarlo directamente, o usarlo como un miembro de instancia en una clase serializable, etc. etc. Veo que es privado, pero asegurándose de que nunca se accederá fuera del actual clase o conjunto de un miembro de instancia está fuera del alcance del compilador (e imposible con la reflexión alrededor de todos modos.)

una posible solución es simplemente evitar que la subclase anónima w estilo/inicializador todos juntos y hacer esto:

private final static HashMap<String, Byte> STRING_MAP = new HashMap<String, Byte>(); 

static { 
    STRING_MAP.put("A", new Byte((byte)12)); 
    STRING_MAP.put("B", new Byte((byte)13)); 
} 

El resultado es casi idéntico en la mayoría de los casos y su código no está salpicado de clases anónimas.

+1

Agregaría que nueve de cada diez veces, las colecciones estáticamente inicializadas como esta tienen la intención de ser inmutables. En ese caso, la biblioteca de Google Collections tiene una buena clase ImmutableMap que puede usar: 'ImmutableMap.of (" A ", (byte) 12," B ", (byte) 13);'. También hay un 'ImmutableMap. constructor() ', necesario para> 5 elementos. – yjo

16

Sin embargo, Java (y Eclipse) se queja de que "La clase serializable no declara un campo estático final serialVersionUID de tipo long". ¿Por qué no se dan cuenta de que la estática no va a ser serializada?

El mensaje de error y el hecho de que tiene una variable de miembro estático final en su clase (al menos, así interpreto su descripción) no tienen nada que ver entre sí.

Su clase implementa la interfaz Serializable, o una de las superclases de su clase hace eso. Entonces el compilador nota que su clase es serializable. Las clases serializables deben tener un campo final estático llamado serialVersionUID que se utiliza para crear versiones cuando serializa instancias de su clase.

El uso de la anotación @SuppressWarnings("serial") hace que el compilador se calle con respecto a la falta de serialVersionUID. Así que sí, puede usar eso para deshacerse del mensaje de advertencia, pero una mejor solución es hacer que su clase no implemente Serializable (directa o indirectamente) si no está destinado a ser serializado.

+0

Ninguna de mis clases no implementa interfaz Serializable (o ninguna de sus superclases). – Lukasz

+1

@Lukas ¿estás seguro? ¿Cómo se ve la jerarquía de tu clase? – Jesper

+0

Eclipse apunta a: HashMap Lukasz

Cuestiones relacionadas