CodeGym /Courses /Java Core /Saving data/Externalizable

Saving data/Externalizable

Java Core
Level 10 , Lesson 6
Available

"Hello, Amigo! I'd like to add a little to what Ellie told you."

Sometimes you need to control the serialization process. Here are some of reasons why:

1) An object is not ready for serialization: its current internal state is in the process of changing.

2) An object contains non-serializable objects, but can convert them into a form that can be easily serialized, e.g. save them as a byte array or something else.

3) An object wants to deserialize all its data as one unit and/or to encrypt it before serialization.

There are many reasons why you might want to perform serialization manually. But we don't want to lose all the advantages that standard serialization offers. After all, our object might use other objects. But they can't be serialized if our object doesn't support serialization.

This situation also has a solution: the Externalizable interface. We must thank Java's visionary creators. Simply replace the Serializable interface with the Externalizable interface, and your class can manage the serialization process manually.

The Externalizable interface has two methods, which the Serializable interface does not, that are called by the Java machine when an object is serialized. This is how it looks:

Code
class Cat implements Externalizable
{
 public String name;
 public int age;
 public int weight;

 public void writeExternal(ObjectOutput out)
 {
  out.writeObject(name);
  out.writeInt(age);
  out.writeInt(weight);
}

 public void readExternal(ObjectInput in)
 {
  name = (String) in.readObject();
  age = in.readInt();
  weight = in.readInt();
 }
}

Remind you of anything?

"Holy moly! This is exactly how we tried to save objects before we considered serialization."

"This makes everything simple: if standard serialization is adequate, we just inherit the Serializable interface. If it's not adequate, then we inherit Externalizable and write our own code to save/load our object."

"But is a class marked Externalizable considered serializable? Can we use such a class to "safely" store references to our serializable classes?"

"Yes. If a class implements Serializable or Externalizable, it is considered serializable."

"It's the perfect solution. I like it."

"I'm happy to hear that. But there's more to it... You should ask Professor Hans about all the nuances. They certainly exist. He wanted to give you something to read."

Comments (6)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Justin Smith Level 41, Greenfield, USA, United States
18 November 2021
I think the code example for using Externalizable would be more helpful if it made it clear why you would want to use it instead of Serializable. The example given would have worked just as well with Serializable. Maybe an example that truly needed to implement Externalizable would have been too long? I don't know the reason, but I don't feel clear at this point when I would need Externalizable over Serializable.
Gellert Varga Level 23, Szekesfehervar, Hungary
13 December 2021
There are three ways to serialize. (I only recently received this summary explanation, but maybe it helps.) 1) Fully automatic. You implement the Serializable interface. If you want to skip a field, you have to use the transient keyword. Usage: objoutstream.writeObject(cat); 2) Automatic, but semi-manual. We have some control over the processes. You implement the Serializable interface. The class to serialize must contain the following methods: private void writeObject(ObjectOutputStream out) throws IOException { } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { } Only inside these methods can the following methods be used: out.defaultWriteObject(); in.defaultReadObject(); Using these will result in a default save/load: non-static and non-transient fields will be saved/read. In addition to using the 'default' method, you can do other operations inside your private writeObject/readObject methods, e.g. save static field, save transient field, change saved instance variable, etc. IMPORTANT! We cannot call these private void write/ReadObject methods ourselves. This version must be used in the same way as above: objoutstream.writeObject(cat); The stream's writeObject method will find the private void writeObject method written in our class, interact with it using a so-called reflection mechanism, and perform the saving of the object as specified in it. 3) Fully manual version. We use the Externalizable interface. Our object to be serialized must contain the following methods: @Override public void writeExternal(ObjectOutput out) throws IOException { } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { } Within these methods, you can completely define yourself what should happen to which field. The suggested usage is the same: objoutstream.writeObject(cat); But in this version 3, the following code also works: cat.writeExternal(objoutstream);
Gellert Varga Level 23, Szekesfehervar, Hungary
25 December 2021
Other important informations: - when using the Externalizable version, the class to be serialized must have a no-args constructor - if the Serializable version is used, all parent classes of the object to be serialized must also be Serializable to allow fully automatic serialization. But if a parent class is not Serializable yet: - fields inherited from such a parent will be left out of the automatic serialization (you will get nulls/zeros to these variables during deserialization), - this not Serializable parent class must have a no-args (default) constructor, otherwise an exception will be thrown during deserialization.
Almas Arshad Level 41, Murree, Pakistan
24 December 2020
Thanks codegym, it is an easy and interesting way of teaching.
fzw Level 41, West University Place, United States
14 April 2020
"After all, our object might use other objects. But they can't be serialized if our object doesn't support serialization." Somehow I feel it should be "After all, our object might be used by other objects. But they can't be serialized if our object doesn't support serialization."
Ewerton Level 30, Belo Horizonte, Brasil
6 July 2019
Come on, old guy! I'm ready.