Serialization - readObject writeObject overrides

94,879

Solution 1

You have to do it like this:

import java.io.IOException;

class Student implements java.io.Serializable {

    String name;
    String DOB;
    int id;

    Student(String naam, int idno, String dob) {
        name = naam;
        id = idno;
        DOB = dob;
    }

    private void writeObject(java.io.ObjectOutputStream stream)
            throws IOException {
        stream.writeObject(name);
        stream.writeInt(id);
        stream.writeObject(DOB);
    }

    private void readObject(java.io.ObjectInputStream stream)
            throws IOException, ClassNotFoundException {
        name = (String) stream.readObject();
        id = stream.readInt();
        DOB = (String) stream.readObject();
    }

    public String toString() {
        return name + "\t" + id + "\t" + DOB + "\t";
    }

}

The readObject is invoked just after creating an instance of Student (bypassing the normal constructor).

Solution 2

I know this question is old, consider this for posterity

Typically you can let the JVM do the hard work by allowing all 'normal' fields to be deserialized automatically:

private void readObject(ObjectInputStream serialized) throws ClassNotFoundException, IOException 
{
    serialized.defaultReadObject();
    // After this, you can handle transient fields or 
    // special initialization that happens in the constructor
}

The documentation for defaultReadObject() is quite clear on this:

Read the non-static and non-transient fields of the current class from this stream. This may only be called from the readObject method of the class being deserialized. It will throw the NotActiveException if it is called otherwise.

Share:
94,879
Quinn
Author by

Quinn

Updated on July 14, 2022

Comments

  • Quinn
    Quinn almost 2 years

    Having written the code below I now have to,use custom readObject() and writeObject() override methods in StudentData to read and write the object's variables. Without using the defaultWriteObject or defaultReadObject methods to do this.

    The trouble is that I don't understand fully what am being asked to do. I have read Uses of readObject/writeObject in Serialization but I can't get my head around it.Can someone point me in the right direction?

    My code:

    import java.io.*; //importing input-output files
    
    class Student implements java.io.Serializable {
    
        String name; // declaration of variables
        String DOB;
        int id;
    
        Student(String naam, int idno, String dob) // Initialising variables to user
                                                    // data
        {
            name = naam;
            id = idno;
            DOB = dob;
        }
    
        public String toString() {
            return name + "\t" + id + "\t" + DOB + "\t";
        }
    
    }
    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.ObjectInputStream;
    import java.io.ObjectOutputStream;
    
    class StudentData                     //main class
    {
        public static void main(String args[]) throws IOException                  //exception handling
        {
            System.out.println("Enter the numbers of students:");
            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            int n = Integer.parseInt(in.readLine());
    
            Student[]  students = new Student[n];
    
            //Student[]  S=new Student[n];                      // array of objects declared and defined
            for (int i = 0; i < students.length; i++) {
                System.out.println("Enter the Details of Student no: " + (i + 1));             //reading data form the user
                System.out.println("Name: ");
                String naam = in.readLine();
                System.out.println("ID no: ");
                int idno = Integer.parseInt(in.readLine());
                System.out.println("DOB: ");               
                String dob = (in.readLine());
    
                students[i] = new Student(naam, idno, dob);                          
    
                File studentFile = new File("StudentData.txt");
                try {
                    FileOutputStream fileOutput = new FileOutputStream(studentFile);
                    ObjectOutputStream objectOutput = new ObjectOutputStream(fileOutput);
                    objectOutput.writeObject(students);
    
                    students = null;
    
                    FileInputStream fileInput = new FileInputStream(studentFile);
                    ObjectInputStream objectInputStream = new ObjectInputStream(fileInput);
    
                    students = (Student[]) objectInputStream.readObject();
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
    
                for (Student student : students) {
                    System.out.println(student);
                }
            }
        }
    }
    
  • Manu Artero
    Manu Artero over 9 years
    Just point a detail there. The order or writing/reading is important. In the example writing is: name, id, DOB so you'll get name, id, DOB when reading
  • antiguru
    antiguru almost 6 years
    The instance is created by the Java serialization framework. It uses an internal API to construct objects without calling the constructor. The Java API shows additional methods a class can implement to intercept the object creation process or supply a different kind of object as a serialized representation.
  • amarnath harish
    amarnath harish over 4 years
    when to use defaultReadObject() and writeobject(o) methods , both gets the job done..
  • mvreijn
    mvreijn over 4 years
    defaultReadObject() is only used when deserializing objects while writeObject() can be overridden for serializing objects.