3

I'm learning about Serializable and Externalizable interface and I see that, when an Externalizable object is reconstructed, an instance is created first using the public no-arg constructor, then the readExternal method is called. If the object does not support Externalizable, then Serializable objects are restored by reading them from an ObjectInputStream.

I don't understand why we use ObjectInputStream for Externalization if the object isn't readed from there? What exactly is readed from the ObjectInputStream? I think we read something from there if we use it.

Also I found this chart about Deserialization Externalizable or Serializable interface

enter image description here

What is the difference between Serializable and Externalizable at the deserialization process?

I don't understand why the Externalizable objects aren't restored by reading them from an ObjectInputStream in the same way like Serializable objects?

ObjectInputStream ois = new ObjectInputStream(
                new FileInputStream("employee.ser"))

I know that the FileInputStream opens a file, creates a sequence of bytes based on the data in the file. The ObjectInputStream takes a sequence of bytes, recreats the object based on the sequence of bytes.

And here is a code.

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

public class Employee implements Externalizable {

    private int id;
    private String name;
    private int age;

    public void Employee() {


    } 

    public int getId() {

        return id;
    }

    public void setId(int id) {

        this.id = id;
    }

    public String getName() {

        return name;
    }

    public void setName(String name) {

        this.name = name;
    }

    public int getAge() {

        return age;
    }

    public void setAge(int age) {

        this.age = age;
    }

    public String toString() {

        return "Employee [id=" + id + ", name=" + name + ", age=" + age + "]";
    }

    public void writeExternal(ObjectOutput oo) throws IOException {

        System.out.println("Inside writeExternal method");
        oo.writeInt(id); 
        oo.writeObject(name); 
    }

    public void readExternal(ObjectInput oi) throws IOException, ClassNotFoundException {

        System.out.println("Inside readExternal method");
        id = oi.readInt();
        name = (String) oi.readObject();
    }
}

ExternalizableWrite

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class ExternalizableWrite {

    public static void main(String args[]) {

        ExternalizableWrite ew = new ExternalizableWrite();
        ew.writeEmployeeObject();
    }

    private void writeEmployeeObject() {

        try (ObjectOutputStream oos = new ObjectOutputStream(
                new FileOutputStream("employee.ser"))) {

            Employee employee = new Employee();
            employee.setId(101);
            employee.setName("Peter"); 
            employee.setAge(25); 

            System.out.println(employee);

            oos.writeObject(employee);  // write the specified object to the ObjectOutputStream

            System.out.println("Successfully written employee object to the file.\n");

        } catch (FileNotFoundException ex) {

            System.out.printf("ERROR: %s", ex); 

        } catch (IOException ex) {

            System.out.printf("ERROR: %s", ex); 
        }
    }
}

ExternalizableRead

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

public class ExternalizableRead {

    public static void main(String args[]) {

        ExternalizableRead er = new ExternalizableRead();
        er.readEmployeeObject();
    }

    private void readEmployeeObject() {

        try (ObjectInputStream ois = new ObjectInputStream(
                new FileInputStream("employee.ser"))) {

            Employee employee = (Employee) ois.readObject();

            System.out.println(employee);

            System.out.println("Successfully read employee objecct to the file.\n");

        } catch (FileNotFoundException ex) {

            System.out.printf("ERROR: %s", ex);

        } catch (IOException | ClassNotFoundException ex) {

            System.out.printf("ERROR: %s", ex);
        } 
    }
}

2 Answers2

0

What is the difference between Serializable and Externalizable at the deserialization process?

According to the implementation of ObjectInputStream, Externalizable objects are handled differently than Serializable objects, as expected:

if (desc.isExternalizable()) {
    readExternalData((Externalizable) obj, desc);
} else {
    readSerialData(obj, desc);
}

As you might expect, the readExternalData method calls Externalizable#readExternal for the object that is being deserialized, while the readSerialData method simply deserializes the serialized fields.

I don't understand why we use ObjectInputStream for Externalization if the object isn't readed from there?

I'm not sure what you're asking, but ObjectInputStream does handle Externalizable objects, as seen above.

I don't understand why the Externalizable objects aren't restored by reading them from an ObjectInputStream in the same way like Serializable objects?

Because Externalizable objects force you to manually serialize and deserialize them, whereas Serializable attempts to serialize all non-static and non-transient fields.

Jacob G.
  • 28,856
  • 5
  • 62
  • 116
0

I don't understand why we use ObjectInputStream for Externalization if the object isn't readed from there?

Externalizable also uses ObjectInputStream.
ObjectInputStream is the parameter that is passed to the readExternal method. One may use methods such as readInt,readFloat etc of the ObjectInputStream to read the values from the serialized object.

What is the difference between Serializable and Externalizable at the deserialization process?

A class (implementing Serializable interface) can customize the data written the serialized object by using the following methods:

private void writeObject(java.io.ObjectOutputStream out) throws IOException

private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException;

Suppose that there are classes A and B like this

  class A implement Serializable {
     writeObject(...){....}
     readObject(...){....}
  } 

  class B extends A implements Serializable{
     writeObject(...){....}
     readObject(...){....}
  }

When an object of B is serialized/de-serialized then writeObject/readObject methods of parent/super class A is called before that of B, thus allowing for parent class' to decide which fields to serialize/de-serialize.

But, when it comes to Externalizable, this does not happen. Only sub-class's readExternal and writeExternal methods are called, overriding the parent's serialization/de-serialization behaviour.

S R Chaitanya
  • 738
  • 7
  • 11