Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Custom Serialization

I have an object that contains a few unserializable fields that I want to serialize. They are from a separate API that I cannot change, so making them Serializable is not an option. The main problem is the Location class. It contains four things that can be serialized that I'd need, all ints. How can I use read/writeObject to create a custom serialization method that can do something like this:

// writeObject: List<Integer> loc = new ArrayList<Integer>(); loc.add(location.x); loc.add(location.y); loc.add(location.z); loc.add(location.uid); // ... serialization code  // readObject: List<Integer> loc = deserialize(); // Replace with real deserialization location = new Location(loc.get(0), loc.get(1), loc.get(2), loc.get(3)); // ... more code 

How can I do this?

like image 850
Alexis King Avatar asked Sep 03 '11 02:09

Alexis King


People also ask

Can you customize serialization in Java?

Customized serialization can be implemented using the following two methods: private void writeObject(ObjectOutputStream oos) throws Exception: This method will be executed automatically by the jvm(also known as Callback Methods) at the time of serialization.

Can you customize serialization process?

We can customize Serialization process by defining writeObject() method & DeSerialization process by defining readObject() method. We have serialized id and name manually writing them in file.


2 Answers

Java supports Custom Serialization. Read the section Customize the Default Protocol.

To quote:

There is, however, a strange yet crafty solution. By using a built-in feature of the serialization mechanism, developers can enhance the normal process by providing two methods inside their class files. Those methods are:

  • private void writeObject(ObjectOutputStream out) throws IOException;
  • private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;

In this method, what you could do is serialize it into other forms if you need to such as the ArrayList for Location that you illustrated or JSON or other data format/method and reconstruct it back on readObject()

With your example, you add the following code:

  private void writeObject(ObjectOutputStream oos) throws IOException {     // default serialization      oos.defaultWriteObject();     // write the object     List loc = new ArrayList();     loc.add(location.x);     loc.add(location.y);     loc.add(location.z);     loc.add(location.uid);     oos.writeObject(loc); }  private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {     // default deserialization     ois.defaultReadObject();     List loc = (List)ois.readObject(); // Replace with real deserialization     location = new Location(loc.get(0), loc.get(1), loc.get(2), loc.get(3));     // ... more code  }  
like image 161
momo Avatar answered Sep 20 '22 21:09

momo


Similar to @momo's answer but without using a List and auto-boxed int values which will make it much more compact.

private void writeObject(ObjectOutputStream oos) throws IOException {     // default serialization      oos.defaultWriteObject();     // write the object     oos.writeInt(location.x);     oos.writeInt(location.y);     oos.writeInt(location.z);     oos.writeInt(location.uid); }  private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {     // default deserialization     ois.defaultReadObject();     location = new Location(ois.readInt(), ois.readInt(), ois.readInt(), ois.readInt());     // ... more code  } 
like image 42
Peter Lawrey Avatar answered Sep 18 '22 21:09

Peter Lawrey