2011-05-05 14 views
6

De la descripción de SE_BAD_FIELD: campo de instanciaFindBugs - SE_BAD_FIELD regla, ¿por qué ignora java.lang.Object?

no transitoria no serializable en clase serializable

Esta clase Serializable define un campo de instancia no primitivos que no es ni transitoria, Serializable, o java.lang .Object, y no parece implementar la interfaz Externalizable o los métodos readObject() y writeObject(). Los objetos de esta clase no se deserializarán correctamente si se almacena un objeto no serializable en este campo.

¿Por qué java.lang.Object es una excepción a la regla?

+0

Tal vez los autores esperan que si elige voluntariamente java.lang.Object como el tipo de un atributo (el tipo más general, sobre el que no puede asumir nada) en lugar de un tipo específico, ya sabe que la serialización no puede trabajar razonablemente con respecto a ese campo. Pero estoy de acuerdo en que la excepción es extraña: después de todo, ¡el error podría ser que simplemente olvidaste el modificador transitorio! –

+0

Podría tener algo que ver con objetos de bloqueo. – Matt

+0

O quizás matrices. –

Respuesta

1

Porque todo se puede deserializar en un java.lang.Object ya que cada clase en java extiende java.lang.Object. Si logra serializar un objeto que tiene un campo no serializable, no tiene forma de conocer la clase de ese campo en la deserialización. Como cada clase es un objeto, siempre puede recurrir a la clase Object.

class NonSerializableUser {} 
    class SerializableUser implements Serializable{} 

    class SomeObject implements Serializable{ 
     public NonSerializableUser nonUser; 
     public SerializableUser user; 
     public Object nonUserObj; 

     public SomeObject(SerializableUser u, NonSerializableUser uu, NonSerializableUser uuu){ 
      user = u; 
      nonUser = uu; 
      nonUserObj = uuu; 
     } 
    } 

En este ejemplo deserializar esta clase resultaría en no usuarios de ser nula, siendo usuario de la instancia de clase SerializableUser correcta, y nonUserObj sería no nulo sin embargo, se han perdido todos los métodos y campos NonSerializableClass, no tendrán sido serializado Las únicas partes de esa instancia que se serializan son los métodos y campos que pertenecen a Object.

Vale la pena señalar que muchas bibliotecas de serialización (ObjectOutputStream por ejemplo) se quejarán de la clase no serializable y no serializarán este objeto en primer lugar. Es por eso que dejé fuera los detalles del paso de serialización/deserialización. Sin embargo, muchos frameworks xml aún serializarán estas clases y esta tiende a ser la situación en la que este error aumenta.

2

El número de falsos positivos sería potencialmente alto, como

public void writeIt(Object o, ObjectOutputStream oos) { 
    oos.writeObject(o); 
} 

podría ser perfectamente bien, como la persona que llama pasa siempre en una instancia de una clase derivada que es Serializable.

Ahora la pregunta es, ¿por qué no es el método anterior firma

public void writeIt(Serializable o, ObjectOutputStream oos) { 
    oos.writeObject(o); 
} 

la respuesta es que entonces todo tipo de objetos definidos por las interfaces pasa como primer parámetro fallarían para compilar.

como

Map m = ..... 
writeIt(m, oos); 

por lo que el valor de la captura de serializar java.lang.Object (que es probablemente un evento extremadamente raro) no vale la pena el impacto positivo falso.

Cuestiones relacionadas