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?
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.
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.
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 }
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 }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With