2010-02-18 10 views
176

Tengo el mensaje de advertencia en el título. Me gustaría entender y eliminarlo. Ya encontré algunas respuestas sobre esta pregunta, pero no entiendo estas respuestas debido a una sobrecarga de términos técnicos. ¿Es posible explicar este problema con palabras simples?¿Qué significa: la clase serializable no declara un campo serialVersionUID final estático?

P.S. Sé lo que OOP es. Sé lo que es objeto, clase, método, campo e instanciación.

P.P.S. Si alguien necesita mi código es aquí:

import java.awt.*; 
import javax.swing.*; 


public class HelloWorldSwing extends JFrame { 

     JTextArea m_resultArea = new JTextArea(6, 30); 

     //====================================================== constructor 
     public HelloWorldSwing() { 
      //... Set initial text, scrolling, and border. 
      m_resultArea.setText("Enter more text to see scrollbars"); 
      JScrollPane scrollingArea = new JScrollPane(m_resultArea); 
      scrollingArea.setBorder(BorderFactory.createEmptyBorder(10,5,10,5)); 

      // Get the content pane, set layout, add to center 
      Container content = this.getContentPane(); 
      content.setLayout(new BorderLayout()); 
      content.add(scrollingArea, BorderLayout.CENTER); 
      this.pack(); 
     } 

     public static void createAndViewJFrame() { 
      JFrame win = new HelloWorldSwing(); 
      win.setTitle("TextAreaDemo"); 
      win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      win.setVisible(true); 
     } 

     //============================================================= main 
     public static void main(String[] args) { 
      SwingUtilities.invokeLater(new Runnable(){ 
       public void run(){ 
        createAndViewJFrame(); 
       } 
      }); 
     } 

} 
+0

¿Puede ser que el mensaje de advertencia discutido sea una razón por la que se congele mi aplicación GUI? – Roman

+0

no, nada que ver con la congelación de tu gui. – james

+2

Dup: http://stackoverflow.com/questions/285793/why-should-i-bother-about-serialversionuid – skaffman

Respuesta

132

Desde el javadoc:

La serialización asociados de tiempo de ejecución con cada clase serializable un número de versión, llamada serialVersionUID, que se utiliza durante la deserialización para verificar que el emisor y el receptor de un objeto serializado tienen clases cargadas para ese objeto que son compatibles con respecto a la serialización. Si el receptor ha cargado una clase para el objeto que tiene un serialVersionUID diferente al de la clase del remitente correspondiente, la deserialización dará como resultado un InvalidClassException. Una clase serializable puede declarar su propia serialVersionUID explícitamente por la que se declara un campo denominado "serialVersionUID" que debe ser estática, final y de tipo long:

Es posible configurar el IDE para:

  • ignoran esto, en vez de dar una advertencia.
  • autogenerate un id

Según su pregunta adicional "¿Es posible que el mensaje de advertencia discutido es una razón por la que mi aplicación GUI congelar?":

No, no puede ser. Puede causar un problema solo si está serializando objetos y deserializándolos en un lugar (o tiempo) diferente donde (cuando) la clase ha cambiado, y no dará como resultado la congelación, sino en InvalidClassException.

+7

También puede dejar que su IDE genere automáticamente uno. – BalusC

+4

@BalusC - ¿cómo podemos hacer eso en eclipse? ¿Es seguro generar automáticamente? –

+4

@JediKnight En Eclispse está Ventana> Preferencias> Java> Estilo de código> Limpieza> Código faltante> active "Agregar ID de versión de serie" en "Posibles problemas de programación". Luego, si está en el perfil predeterminado, obviamente debe guardarlo como uno diferente. – 0x41414141

5

Cualquier clase que se pueda serializar (es decir, implementa Serializable) debe declarar ese UID y debe cambiarse cada vez que haya cambios que afecten a la serialización (campos adicionales, campos eliminados, cambio de orden de campos, ...). El valor del campo se verifica durante la deserialización y si el valor del objeto serializado no es igual al valor de la clase en la máquina virtual actual, se lanza una excepción.

Tenga en cuenta que este valor es especial ya que se serializa con el objeto aunque sea estático, por los motivos descritos anteriormente.

+2

¿JFrame una clase serializable? ¿Qué es el UID y cómo puedo declararlo? ¿Mi código "cambia algo que afecta la serialización"? ¿Qué significa en realidad la serialización? – Roman

+0

Sí, JFrame es un java.awt.Component que implementa Serializable. El código nunca cambia nada que afecte la serialización, solo los programadores hacen eso. No conozco una lista que enumere todos los cambios que afectan la serialización. Consulte http://en.wikipedia.org/wiki/Serialization#Java para obtener una descripción de la serialización en Java. –

+2

No está serializado con el objeto. No debe cambiarse a menos que quiera romper la compatibilidad, o si ya lo hizo al apartarse de lo que dice en la sección de Versiones de la especificación. Eso no incluye agregar o reordenar campos. La referencia correcta no es Wikipedia, sino la especificación de serialización de objetos. – EJP

31

Las razones para la advertencia están documentadas here, y las correcciones simples son para desactivar la advertencia o poner la siguiente declaración en su código para suministrar la versión UID. El valor real no es relevante, comience con 999 si lo desea, pero cambiarlo cuando realice cambios incompatibles en la clase es.

public class HelloWorldSwing extends JFrame { 

     JTextArea m_resultArea = new JTextArea(6, 30); 
     private static final long serialVersionUID = 1L; 
+1

Los motivos de la advertencia están documentados en la especificación de serialización de objetos Java y en [Javadoc] (http://docs.oracle.com/javase/7/docs/api/java/io/Serializable.html). Las respuestas de StackOverflow no son referencias normativas. – EJP

27

debe ser cambiado cada vez que algo cambios que afectan a la serialización (campos adicionales, campos retirados, cambio de orden de los campos, ...)

Eso no es correcto, y no podrá citar una fuente autorizada para esa afirmación. Se debe cambiarse cada vez que hagas un cambio que es incompatible con arreglo a las reglas establecidas en la sección Versioning of Serializable Objects del Object Serialization Specification, lo que hace específicamente no incluyen campos o cambio de orden de los campos, y adicionales cuando no se ha proporcionado y readObject(), writeObject(),/o readResolve() o /writeReplace() métodos y/o una declaración serializableFields que podría hacer frente al cambio.

30

Las otras respuestas hasta ahora tienen mucha información técnica. Trataré de responder, como solicité, en términos simples.

Serialización es lo que le hace a una instancia de un objeto si desea volcarlo en un búfer en bruto, guardarlo en un disco, transportarlo en una secuencia binaria (por ejemplo, enviar un objeto a través de un zócalo de red) o de lo contrario, crea una representación binaria serializada de un objeto. (Para obtener más información sobre la serialización, ver Java Serialization on Wikipedia).

Si no tiene intención de serializar su clase, puede agregar la anotación justo encima de su clase @SuppressWarnings("serial").

Si vas a serializar, entonces tienes un montón de cosas de qué preocuparse, todas centradas en el uso correcto del UUID. Básicamente, el UUID es una forma de "versionar" un objeto que serializaría, de modo que cualquier proceso que se deserialice sepa que se está deserializando correctamente. Me gustaría ver Ensure proper version control for serialized objects para más información.

+0

Hay varios * errores * importantes en su cita, y también algunas autocontradicciones. – EJP

+11

@EJP Sería útil para todos si enumeró los errores. – MrMas

+0

@EJP Se ​​me acaba de ocurrir que hay dos citas en mi respuesta. ¿A qué cita estás refiriendo? – MrMas

Cuestiones relacionadas