jeudi 16 avril 2015

Serializing Java Objects with Non-Serializable Attributes

There are multiple reasons one might want to use custom serialization instead of relying on Java’s default serialization. One of the most common reasons is for performance improvements, but another reason for writing custom serialization is when the default serialization mechanism is unsupported. Specifically, as will be demonstrated in this post, custom serialization can be used to allow a larger object to be serialized even when attributes of that object are not themselves directly serializable. The next code listing shows a simple class for serializing a given class to a file of the provided name and for deserializing an object from that same file. I will be using it in this post to demonstrate serialization.

SerializationDemonstrator.java

package dustin.examples.serialization;

import static java.lang.System.out;

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

/**
 * Simple serialization/deserialization demonstrator.
 * 
 * @author Dustin
 */
public class SerializationDemonstrator
{
   /**
    * Serialize the provided object to the file of the provided name.
    * @param objectToSerialize Object that is to be serialized to file; it is
    *     best that this object have an individually overridden toString()
    *     implementation as that is used by this method for writing our status.
    * @param fileName Name of file to which object is to be serialized.
    * @throws IllegalArgumentException Thrown if either provided parameter is null.
    */
   public static  void serialize(final T objectToSerialize, final String fileName)
   {
      if (fileName == null)
      {
         throw new IllegalArgumentException(
            "Name of file to which to serialize object to cannot be null.");
      }
      if (objectToSerialize == null)
      {
         throw new IllegalArgumentException("Object to be serialized cannot be null.");
      }
      try (FileOutputStream fos = new FileOutputStream(fileName);
           ObjectOutputStream oos = new ObjectOutputStream(fos))
      {
         oos.writeObject(objectToSerialize);
         out.println("Serialization of Object " + objectToSerialize + " completed.");
      }
      catch (IOException ioException)
      {
         ioException.printStackTrace();
      }
   }

   /**
    * Provides an object deserialized from the file indicated by the provided
    * file name.
    * 
    * @param  Type of object to be deserialized.
    * @param fileToDeserialize Name of file from which object is to be deserialized.
    * @param classBeingDeserialized Class definition of object to be deserialized
    *    from the file of the provided name/path; it is recommended that this
    *    class define its own toString() implementation as that will be used in
    *    this method's status output.
    * @return Object deserialized from provided filename as an instance of the
    *    provided class; may be null if something goes wrong with deserialization.
    * @throws IllegalArgumentException Thrown if either provided parameter is null.
    */
   public static  T deserialize(final String fileToDeserialize, final Class classBeingDeserialized)
   {
      if (fileToDeserialize == null)
      {
         throw new IllegalArgumentException("Cannot deserialize from a null filename.");
      }
      if (classBeingDeserialized == null)
      {
         throw new IllegalArgumentException("Type of class to be deserialized cannot be null.");
      }
      T objectOut = null;
      try (FileInputStream fis = new FileInputStream(fileToDeserialize);
           ObjectInputStream ois = new ObjectInputStream(fis))
      {
         objectOut = (T) ois.readObject();
         out.println("Deserialization of Object " + objectOut + " is completed.");
      }
      catch (IOException | ClassNotFoundException exception)
      {
         exception.printStackTrace();
      }
      return objectOut;
   }
}
The next code listing illustrates use of the SerializationDemonstrator class to serialize and deserialize a standard Java string (which is Serializable). A screen snapshot follows the code listing and shows the output (in NetBeans) of running that String through the serialize and deserialize methods of the SerializationDemonstrator class.

Running SerializationDemonstrator Methods on String


SerializationDemonstrator.serialize("Inspired by Actual Events", "string.dat");
final String stringOut = SerializationDemonstrator.deserialize("string.dat", String.class);

The next two code listings are for the class Person.java and a class that it has as an attribute type (CityState.java). Although Person implements Serializable, the CityAndState class does not.

Person.java

package dustin.examples.serialization;

import java.io.Serializable;

/**
 * Person class.
 * 
 * @author Dustin
 */
public class Person implements Serializable
{
   private String lastName;
   private String firstName;
   private CityState cityAndState;

   public Person(
      final String newLastName, final String newFirstName,
      final CityState newCityAndState)
   {
      this.lastName = newLastName;
      this.firstName = newFirstName;
      this.cityAndState = newCityAndState;
   }

   public String getFirstName()
   {
      return this.firstName;
   }

   public String getLastName()
   {
      return this.lastName;
   }

   @Override
   public String toString()
   {
      return this.firstName + " " + this.lastName + " of " + this.cityAndState;
   }
}

CityAndState.java
package dustin.examples.serialization;

/**
 * Simple class storing city and state names that is NOT Serializable.
 * 
 * @author Dustin
 */
public class CityState
{
   private final String cityName;
   private final String stateName;

   public CityState(final String newCityName, final String newStateName)
   {
      this.cityName = newCityName;
      this.stateName = newStateName;
   }

   public String getCityName()
   {
      return this.cityName;
   }

   public String getStateName()
   {
      return this.stateName;
   }

   @Override
   public String toString()
   {
      return this.cityName + ", " + this.stateName;
   }
}

Unknown

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation.
Templates blogger

0 commentaires:

Enregistrer un commentaire

 

Copyright @ 2013 Code4Pro.