What is the difference between Serializable and Externalizable in Java?

后端 未结 11 1114
轻奢々
轻奢々 2020-11-22 12:31

What is the difference between Serializable and Externalizable in Java?

11条回答
  •  春和景丽
    2020-11-22 13:22

    Object Serialization uses the Serializable and Externalizable interfaces. A Java object is only serializable. if a class or any of its superclasses implements either the java.io.Serializable interface or its subinterface, java.io.Externalizable. Most of the java class are serializable.

    • NotSerializableException: packageName.ClassName « To participate a Class Object in serialization process, The class must implement either Serializable or Externalizable interface.


    Serializable Interface

    Object Serialization produces a stream with information about the Java classes for the objects which are being saved. For serializable objects, sufficient information is kept to restore those objects even if a different (but compatible) version of the implementation of the class is present. The Serializable interface is defined to identify classes which implement the serializable protocol:

    package java.io;
    
    public interface Serializable {};
    
    • The serialization interface has no methods or fields and serves only to identify the semantics of being serializable. For serializing/deserializing a class, either we can use default writeObject and readObject methods (or) we can overriding writeObject and readObject methods from a class.
    • JVM will have complete control in serializing the object. use transient keyword to prevent the data member from being serialized.
    • Here serializable objects is reconstructed directly from the stream without executing
    • InvalidClassException « In deserialization process, if local class serialVersionUID value is different from the corresponding sender's class. then result's in conflict as java.io.InvalidClassException: com.github.objects.User; local class incompatible: stream classdesc serialVersionUID = 5081877, local class serialVersionUID = 50818771
    • The values of the non-transient and non-static fields of the class get serialized.

    Externalizable Interface

    For Externalizable objects, only the identity of the class of the object is saved by the container; the class must save and restore the contents. The Externalizable interface is defined as follows:

    package java.io;
    
    public interface Externalizable extends Serializable
    {
        public void writeExternal(ObjectOutput out)
            throws IOException;
    
        public void readExternal(ObjectInput in)
            throws IOException, java.lang.ClassNotFoundException;
    }
    
    • The Externalizable interface has two methods, an externalizable object must implement a writeExternal and readExternal methods to save/restore the state of an object.
    • Programmer has to take care of which objects to be serialized. As a programmer take care of Serialization So, here transient keyword will not restrict any object in Serialization process.
    • When an Externalizable object is reconstructed, an instance is created using the public no-arg constructor, then the readExternal method called. Serializable objects are restored by reading them from an ObjectInputStream.
    • OptionalDataException « The fields MUST BE IN THE SAME ORDER AND TYPE as we wrote them out. If there is any mismatch of type from the stream it throws OptionalDataException.

      @Override public void writeExternal(ObjectOutput out) throws IOException {
          out.writeInt( id );
          out.writeUTF( role );
          out.writeObject(address);
      }
      @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
          this.id = in.readInt();
          this.address = (Address) in.readObject();
          this.role = in.readUTF();
      }
      
    • The instance fields of the class which written (exposed) to ObjectOutput get serialized.


    Example « implements Serializable

    class Role {
        String role;
    }
    class User extends Role implements Serializable {
    
        private static final long serialVersionUID = 5081877L;
        Integer id;
        Address address;
    
        public User() {
            System.out.println("Default Constructor get executed.");
        }
        public User( String role ) {
            this.role = role;
            System.out.println("Parametarised Constructor.");
        }
    }
    
    class Address implements Serializable {
    
        private static final long serialVersionUID = 5081877L;
        String country;
    }
    

    Example « implements Externalizable

    class User extends Role implements Externalizable {
    
        Integer id;
        Address address;
        // mandatory public no-arg constructor
        public User() {
            System.out.println("Default Constructor get executed.");
        }
        public User( String role ) {
            this.role = role;
            System.out.println("Parametarised Constructor.");
        }
    
        @Override
        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeInt( id );
            out.writeUTF( role );
            out.writeObject(address);
        }
        @Override
        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            this.id = in.readInt();
            this.address = (Address) in.readObject();
            this.role = in.readUTF();
        }
    }
    

    Example

    public class CustomClass_Serialization {
        static String serFilename = "D:/serializable_CustomClass.ser";
    
        public static void main(String[] args) throws IOException {
            Address add = new Address();
            add.country = "IND";
    
            User obj = new User("SE");
            obj.id = 7;
            obj.address = add;
    
            // Serialization
            objects_serialize(obj, serFilename);
            objects_deserialize(obj, serFilename);
    
            // Externalization
            objects_WriteRead_External(obj, serFilename);
        }
    
        public static void objects_serialize( User obj, String serFilename ) throws IOException{
            FileOutputStream fos = new FileOutputStream( new File( serFilename ) );
            ObjectOutputStream objectOut = new ObjectOutputStream( fos );
    
            // java.io.NotSerializableException: com.github.objects.Address
            objectOut.writeObject( obj );
            objectOut.flush();
            objectOut.close();
            fos.close();
    
            System.out.println("Data Stored in to a file");
        }
        public static void objects_deserialize( User obj, String serFilename ) throws IOException{
            try {
                FileInputStream fis = new FileInputStream( new File( serFilename ) );
                ObjectInputStream ois = new ObjectInputStream( fis );
                Object readObject;
                readObject = ois.readObject();
                String calssName = readObject.getClass().getName();
                System.out.println("Restoring Class Name : "+ calssName); // InvalidClassException
    
                User user = (User) readObject;
                System.out.format("Obj[Id:%d, Role:%s] \n", user.id, user.role);
    
                Address add = (Address) user.address;
                System.out.println("Inner Obj : "+ add.country );
                ois.close();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    
        public static void objects_WriteRead_External( User obj, String serFilename ) throws IOException {
            FileOutputStream fos = new FileOutputStream(new File( serFilename ));
            ObjectOutputStream objectOut = new ObjectOutputStream( fos );
    
            obj.writeExternal( objectOut );
            objectOut.flush();
    
            fos.close();
    
            System.out.println("Data Stored in to a file");
    
            try {
                // create a new instance and read the assign the contents from stream.
                User user = new User();
    
                FileInputStream fis = new FileInputStream(new File( serFilename ));
                ObjectInputStream ois = new ObjectInputStream( fis );
    
                user.readExternal(ois);
    
                System.out.format("Obj[Id:%d, Role:%s] \n", user.id, user.role);
    
                Address add = (Address) user.address;
                System.out.println("Inner Obj : "+ add.country );
                ois.close();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
    

    @see

    • What is Object Serialization
    • Object Serialization: Frequently Asked Questions

提交回复
热议问题