Herramientas de usuario

Herramientas del sitio


bloque4:serializable

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anteriorRevisión previa
Próxima revisión
Revisión previa
bloque4:serializable [12/03/2018 10:36] – [Escritura de objetos en fichero] Fernando Valdeónbloque4:serializable [04/09/2018 08:06] (actual) – borrado Fernando Valdeón
Línea 1: Línea 1:
-====== Herencias: Interfaz Serializable ====== 
-Cuando una clase implementa una interface, obliga a sobrescribir los métodos de esa interface. En Java tenemos muchas interfaces para hacer que nuestras clases tengan una forma común. La interfaz Serializable sirve para poder indicar que un objeto puede ser serializado; guardarlo en fichero como un objeto tal cual. 
  
-https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html 
- 
-===== Interface Serializable ===== 
-Para que un programa en java pueda convertir un objeto en un montón de bytes y pueda luego recuperarlo, el objeto necesita ser Serializable. Al poder convertir el objeto a bytes, ese objeto se puede enviar a través de red, guardarlo en un fichero, y después reconstruirlo al otro lado de la red, leerlo del fichero, etc. 
- 
-Para que un objeto sea serializable debe implementar la interface Serializable. La interface Serializable es algo peculiar ya que no tiene métodos. Basta con implementarla y ya podremos serializar nuestros objetos. 
- 
-Hay que tener en cuenta que, para poder traducir un objeto a bytes de forma correcta, todos los objetos que lo componen deben ser serializables.  
-La mayoría de las clases de la [[https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html|API]] de Java implementan esta interface, pero nuestros objetos deben implementarla también si queremos serializarlos.  
-<code java> 
-public class Coche implements Serializable{ 
- private String matricula; 
- private Persona conductor;  
- 
-//El atributo conductor también debe ser serializable 
-} 
-</code> 
- 
-Si dentro de la clase Coche hay atributos de otras clases, deben ser también serializables. Como decimos, con la mayoría de objetos de Java no hay problema, pero sí con los nuestros propios. 
- 
-En el caso anterior el atributo conductor de tipo Persona debe ser también serializable, por lo que la clase Persona debe implementar también dicha interface. 
- 
-==== Serial Version UID ==== 
- 
-Cuando pasamos objetos Serializable de un lado a otro tenemos un pequeño problema. Si la clase que queremos pasar es Coche, lo normal es que en ambos lados (el que envía y el que recibe la clase), tengan su propia copia del fichero Coche.class.  
-Pero también es posible que en distintas versiones de nuestro programa la clase Coche cambie, de forma que es posible que un lado tenga una versión más antigua que en el otro lado. Si sucede esto, la reconstrucción de la clase en el lado que recibe sera imposible.  
- 
-Para evitar este problema, se aconseja que la clase Coche tenga un atributo privado de esta forma: 
-<code java> 
-private static final long serialVersionUID = 8799656478674716638L; 
-</code> 
- 
-de forma que el numerito que ponemos al final debe ser distinto para cada versión de compilado que tengamos. De esta forma, java es capaz de detectar rápidamente que las versiones de Coche.class en ambos lados son distintas o iguales. 
- 
-Algunos entornos de desarrollo, como eclipse, dan un warning si una clase que implementa Serializable (o hereda de una clase que a su vez implementa Serializable) no tiene definido este campo. Es más, puede generarlo automáticamente, número incluido, si se lo pedimos. En eclipse basta con hacer click con el ratón sobre el símbolo de warning para que nos de las posibles soluciones al warning. Una de ellas genera el número automáticamente. 
- 
-==== Escritura de objetos en fichero ==== 
- 
-Es posible utilizar los mecanismos de serialización disponibles para serializar un objeto guardándolo en un fichero. 
- 
-Tenemos un flujo de datos concreto para ficheros: **FileOutputStream**. El constructor de esta clase puede crear un flujo hacia un fichero a partir de un objeto File o de un String con la ruta. 
- 
-El flujo de datos **ObjectOutputStream** está especializado en la escritura de objetos. Necesita que le indiquemos que su flujo de escritura será hacia un fichero, a partir de un objeto FileOutputStream.  
- 
-Esto se puede realizar en una sola línea:  
-<code java> 
-ObjectOutputStream salida=new ObjectOutputStream(new FileOutputStream(new File("fichero.bin")); 
-</code> 
- 
-O en líneas diferentes: 
- 
-<code java> 
-File fichero = new File("fichero.bin"); 
-FileOutputStream flujoFichero = new FileOutputStream(fichero); 
-ObjectOutputStream flujoObjetos = new ObjectOutputStream(fos); 
-</code> 
- 
-El método writeObject de la clase ObjectOutputStream escribe los objetos al flujo de salida y los guarda en un fichero de disco. 
- 
-<code java> 
-Coche miCoche1 = new Coche(); 
-Coche miCoche2 = new Coche(); 
- 
-// Escribir objetos en el fichero 
-flujoObjetos.writeObject("Guardo 2 objetos Coche"); //Puedo almacenar objetos String 
-flujoObjetos.writeObject(miCoche1);     // u objetos tipo Coche 
-flujoObjetos.writeObject(miCoche2); 
-. . . 
-flujoObjetos.close(); // Finalmente se cierran los flujos de salida, cerrando el más externo. 
-</code> 
- 
-Puedo serializar estructuras completas, como arraylists o arrays, o cualquier clase que contenga cualquier estructura, sin necesidad de serializar por separado sus elementos. 
- 
-==== Lectura de objetos en fichero ==== 
- 
-El proceso de lectura desde fichero es paralelo al de escritura. Debo usar los flujos anteriores, pero en este caso deben ser de lectura: 
-  * Flujo de entrada desde fichero: FileImputStream 
-  * Flujo de entrada de objetos: ObjectInputStrem 
-  * Método de ObjectInputStream para lectura de objetos: readObject() 
-<code java> 
-File fichero = new File("fichero.bin"); 
-FileInputStream fis = new FileInputStream(fichero); 
-ObjectInputStream entrada = new ObjectInputStream(fis); 
- 
-// Leer el objeto del fichero (en el mismo orden !!) 
-String cadena = (String) entrada.readObject(); //Leo el objeto tipo String 
-Coche cocheLeido1 = (Coche) entrada.readObject(); //Leo los objetos tipo Coche 
-Coche cocheLeido2 = (Coche) entrada.readObject(); 
- 
-entrada.close(); //Finalmente se cierran los flujos de entrada 
-</code> 
- 
-Como hemos visto en otras ocasiones las clases de trabajo con ficheros suelen lanzar excepciones que debemos de controlar con la estructura try-catch-finally. 
- 
-=== Warnings al hacer casting de un objeto leído === 
- 
-En el caso de lectura de objetos, nuestro programa no se puede asegurar de ninguna rápida que los bytes que lee del fichero son los tipos de datos que nosotros le indicamos: 
-<code java> 
-Coche cocheLeido1 = (Coche) entrada.readObject(); 
-</code> 
-Aunque nosotros sepamos que se lee lo correcto no hay forma de que Java “lo sepa”. Podríamos cambiar el fichero, y no leer el objeto que esperamos leer.  
- 
-Por lo tanto, Eclipse nos indica un warning al hacer un casting de bytes leidos desde fichero. La manera más sencilla de eliminarlo es añadiendo la siguiente linea al comienzo del método que genera dicha advertencia: 
-<code java> 
-@SuppressWarnings("unchecked") 
-</code> 
- 
----- 
-(c) {{date> %Y}} Fernando Valdeón 
bloque4/serializable.1520851003.txt.gz · Última modificación: 16/09/2024 20:53 (editor externo)