2012-06-12 11 views
25

Me he encontrado con la comprensión de la serialización de Java. He leído en muchos documentos y libros que las variables estáticas y transitorias no se pueden serializar en Java. Declaramos un serialVersionUid de la siguiente manera.Son variables estáticas serializadas en el proceso de serialización

private static final long serialVersionUID = 1L; 

Si una variable estática no se serializó, a menudo nos enfrentamos a una excepción durante el proceso de deserialización.

java.io.InvalidClassException 

en la que se extrae y se compara con la serialVersionUID de la clase cargada la serialVersionUID desde el objeto deserializado.

Que yo sepa, creo que si las variables estáticas no se pueden serializar. No tiene sentido esa excepción. Puedo estar equivocado porque todavía estoy aprendiendo.

Es un mito que "las variables estáticas y transitorias en java no se pueden serializar". Por favor corrígeme, estoy en un lío acerca de este concepto.

Respuesta

39

serialVersionUID es una variable estática especial utilizada por el proceso de serialización y deserialización, para verificar que una clase local sea compatible con la clase utilizada para serializar un objeto. No es solo una variable estática como otras, que definitivamente no están serializadas.

Cuando se serializa un objeto de una clase, el nombre de clase y el UID de la versión en serie se escriben en la secuencia de bytes. Cuando se deserializa, la JVM comprueba si la UID de la versión en serie leída de la secuencia de bytes es la misma que la de la clase local. Si no lo son, ni siquiera trata de deserializar el objeto, porque sabe que las clases son incompatibles.

+0

¿Qué significa el término variable estática especial? – srk

+2

Significa que es una variable estática que es especial. (Específicamente, se trata de manera diferente a otras variables estáticas en la serialización). –

+4

Es especial, porque el mecanismo de serialización busca esta variable estática para saber cuál es el UID de la versión en serie de la clase. Todas las otras variables estáticas simplemente son ignoradas por el mecanismo de serialización. –

3

serialVersionUID es especial y no está sujeto a estas reglas. Hay un código dentro de la maquinaria de serialización que específicamente maneja este campo para realizar las verificaciones de versión automáticas.

48
  1. variables de instancia: Estas variables son serializados, por lo que durante la deserialización alguna de recuperar el estado serializado.

  2. variables estáticas: Estas variables no son serializados, tanto durante la deserialización valor de la variable estática serán cargados desde la clase (se cargará el valor actual.)

  3. Variables transitorios:.transient variables no están serializado, de modo que durante la deserialización esas variables se inicializarán con los valores por defecto correspondientes (por ejemplo, para los objetos null, int0).

  4. Super class variables: Si la superclase también implementó la interfaz Serializable, esas variables se serializarán; de lo contrario, no se serializarán las variables de la superclase. y mientras se deserializa, JVM ejecutará el constructor predeterminado en superclase y completará los valores predeterminados. Lo mismo sucederá con todas las superclases.

+2

"Entonces, mientras el valor de la variable estática de deserialización se cargará desde la clase. (Se cargará el valor actual)." ¿Qué ocurre si la Clase se está deserializando en una JVM diferente? – mdev

+0

@mdev: la afirmación correcta sería que las variables 'estáticas' no se tocan en absoluto. No tiene sentido decir que el "valor de la variable estática se cargará desde la clase" a sí mismo. – Holger

1

Debajo ejemplo explica sobre los estáticas, de instancia transitoria y super clase varialbes serialización y sus salidas.

clase Serializar:

public class SerializeEx extends SuperSerializeEx implements Serializable { 

    private static final long serialVersionUID = 1L; 
    public static int staticNumber = 1234; 
    public int instanceNumber = 1234; 

    public SerializeEx() { 
     staticNumber = 0; 
     instanceNumber = 0; 
     System.out.println("---sub class constructor---"); 
    } 

    public SerializeEx(int staticNumber, int instanceNumber, int superNumber) { 
     super(superNumber); 
     this.staticNumber = staticNumber; 
     this.instanceNumber = instanceNumber; 
    } 
} 

Súper Clase:

public class SuperSerializeEx { 

    public int superNumber; 

    public SuperSerializeEx() { 
     System.out.println("---super class constructor---"); 
     this.superNumber = 1000; 
    } 

    public SuperSerializeEx(int superNumber) { 
     this.superNumber = superNumber; 
    } 
} 

serialización & Deserialización:

public class MainSerialization { 

    public static void main(String[] args) { 
     String fileName = "testing.txt"; 
     serialize(fileName); 
     deSerialize(fileName); 
    } 

    public static void serialize(String fileName) { 
     System.err.println("Serialize....."); 
     SerializeEx serializeMe = new SerializeEx(10, 10, 10); 
     FileOutputStream fos = null; 
     ObjectOutputStream out = null; 
     try { 
      fos = new FileOutputStream(fileName); 
      out = new ObjectOutputStream(fos); 
      out.writeObject(serializeMe); 
      out.close(); 
     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } 
    } 

    public static void deSerialize(String fileName) { 
     System.err.println("DeSerialize....."); 
     SerializeEx time = null; 
     FileInputStream fis = null; 
     ObjectInputStream in = null; 
     try { 
      fis = new FileInputStream(fileName); 
      in = new ObjectInputStream(fis); 
      time = (SerializeEx) in.readObject(); 
      in.close(); 
     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } catch (ClassNotFoundException ex) { 
      ex.printStackTrace(); 
     } 
     System.err.println("Instance Numer = " + time.instanceNumber + " \tStatic Number= " + time.staticNumber + " \t Super Number= " + time.superNumber); 
     SerializeEx serializeMe = new SerializeEx(1001, 1001, 1001); //Modifying the static and instnce variables 
     System.err.println("Instance Numer = " + time.instanceNumber + " \tStatic Number= " + time.staticNumber + " \t Super Number= " + time.superNumber); 
    } 
} 

Salida:

---super class constructor--- 
Serialize..... 
DeSerialize..... 
Instance Numer = 10  Static Number= 10  Super Number= 1000 
Instance Numer = 10  Static Number= 1001 Super Number= 1000 
1

import java.io.FileInputStream; 
 
import java.io.FileNotFoundException; 
 
import java.io.FileOutputStream; 
 
import java.io.IOException; 
 
import java.io.ObjectInputStream; 
 
import java.io.ObjectOutputStream; 
 
import java.io.Serializable; 
 

 
class TestJava implements Serializable{ 
 
    public static int k = 10; 
 
    public int j=5; 
 
public static void main(String[] args) { 
 
    
 
    TestJava tj1= new TestJava(); 
 
    TestJava tj2; 
 
    
 
    
 
     try{ //serialization 
 
      FileOutputStream fos = new FileOutputStream("myclass.ser"); 
 
      ObjectOutputStream oos = new ObjectOutputStream(fos); 
 
      oos.writeObject(tj1); 
 
      oos.close(); 
 
      fos.close(); 
 
      System.out.println("object serielized 1..."+tj1.j); 
 
      System.out.println("object serielized 2..."+tj1.k); 
 
      System.out.println("object serielized 3..."+k); 
 
      k=++k; // 'k' value incrementd after serialization 
 
      } catch(FileNotFoundException fnfe){ 
 
      fnfe.printStackTrace(); 
 
      } catch(IOException ioex){ 
 
      ioex.printStackTrace(); 
 
      } 
 
    
 
     
 
      try{ //deserialization 
 
       FileInputStream fis = new FileInputStream("myclass.ser"); 
 
       ObjectInputStream ois = new ObjectInputStream(fis); 
 
       tj2 = (TestJava) ois.readObject(); 
 
       ois.close(); 
 
       fis.close(); 
 
       System.out.println("object DEEEEserielized 1..."+tj2.j); 
 
       System.out.println("object DEEEEserielized 2..."+tj2.k); 
 
       System.out.println("object DEEEEserielized 3..."+k); 
 
      // in deserialization 'k' value is shown as incremented. 
 
      // That means Static varialbe 'K' is not serialized. 
 
      // if 'K' value is serialized then, it has to show old value before incrementd the 'K' value. 
 
      } catch(FileNotFoundException fnfe){ 
 
       fnfe.printStackTrace(); 
 
      } catch(IOException ioex){ 
 
       ioex.printStackTrace(); 
 
      } catch(ClassNotFoundException CNFE){ 
 
       CNFE.printStackTrace();     
 
      } 
 
     } 
 
} 
 

 
/* Output of the above program 
 
    
 
object serielized 1...5 
 
object serielized 2...10 
 
object serielized 3...10 
 
object DEEEEserielized 1...5 
 
object DEEEEserielized 2...11 
 
object DEEEEserielized 3...11 
 

 

 
*/

1

El serialVersionUID también es de serie en este caso.

Cualquier variable estática que se proporcione un valor durante la inicialización de clase se serializa.

Sin embargo, en casos normales, donde se proporcionaría el valor de una variable estática en la clase principal/tiempo de ejecución no se serializaría.

Puede intentar acceder al serialVersionUID haciéndolo público e intentar acceder a él después de la deserialización.

Puede consultar "http://javabeginnerstutorial.com/core-java-tutorial/transient-vs-static-variable-java/" para obtener más información.

Espero que ayude. ¡Saludos!

0

No, si una clase tiene una variable estática, al momento de la serialización esa variable se omitirá. porque la variable estática es única para todos los objetos y la serialización se usa solo para guardar las propiedades del objeto (estado del objeto). variable estática es una propiedad de la clase

Cuestiones relacionadas