3

I am trying to write a instance of pojo class by using WriteObject method. when i write code like this :

    private void writeObject(ObjectOutputStream oos) throws IOException,ClassNotFoundException{ 
    oos.defaultWriteObject();    
    oos.writeObject(this);
}

It works fine but when I try and create a new local object and pass it to writeObject method it fails with

Exception in thread "main" java.lang.StackOverflowError

can some one please explain why it keeps calling writeObject method again and again recursively?

class Employee implements Serializable{
    private String name;
    private int age;
    private void readObject(ObjectInputStream ois) throws IOException,ClassNotFoundException{
        ois.defaultReadObject();
        Employee emp = (Employee)ois.readObject();
        emp.toString();
    }
    private void writeObject(ObjectOutputStream oos) throws IOException,ClassNotFoundException{
        oos.defaultWriteObject();
        Employee emp = new Employee("sumit",10);
        oos.writeObject(emp);
    }
    public Employee(){

    }
    public Employee(String name, int age){
        this.name = name;
        this.age = age;
    }   
}
amit kumar
  • 53
  • 6
  • Can you share the entire class code please.. – codeLover Aug 23 '18 at 06:03
  • Link for the code: https://drive.google.com/file/d/1rq6nW0XICDnRFXRp9Hanc14lonK21eiU/view?usp=sharing – amit kumar Aug 23 '18 at 06:35
  • I am unable to access it due to netwrok constraints..is it possible for you to add it here.. – codeLover Aug 23 '18 at 06:38
  • class Employee implements Serializable{ private String name; private int age; private void readObject(ObjectInputStream ois) throws IOException,ClassNotFoundException{ ois.defaultReadObject(); Employee emp = (Employee)ois.readObject(); emp.toString(); } private void writeObject(ObjectOutputStream oos) throws IOException,ClassNotFoundException{ oos.defaultWriteObject(); Employee emp = new Employee("sumit",10); oos.writeObject(emp); } public Employee(){ } public Employee(String name, int age){ this.name = name; this.age = age; } } – amit kumar Aug 23 '18 at 06:50
  • Can you please add it with proper formatting..as code is quite difficult to figure out in this way – codeLover Aug 23 '18 at 06:51
  • I could not format the comment so added in the post itself. – amit kumar Aug 23 '18 at 07:01
  • You should always add things in the post. The comments are for comments, not code. – Kayaman Aug 23 '18 at 07:10

2 Answers2

0

What is happening here is 'Employee' class is serializable. And you have overridden writeObject method in it.

Now in this overridden method, you are again creating an instance of Employee object and calling writeObject method of oos.

Serialization logic checks if the object being added is serializable. If it is, then serialize it or else throw NotSerializable exception.

Here, the object being added is Serializable. Hence it goes to serialize it and found that this Object has writeObject method overridden. So it calls that method.

Now again it goes to your overridden method logic and does the same method call again

oos.defaultWriteObject(); 
Employee emp = new Employee("sumit",10); 
oos.writeObject(emp);

and the loops continue, leading to StackOverflow error as it recursively calls it over and over again without breaking

Ashishkumar Singh
  • 3,580
  • 1
  • 23
  • 41
  • Actually I wanted to understand why it doesn't call recursively when I pass this object to writeObject method: oos.defaultWriteObject(); oos.writeObject(this); – amit kumar Aug 23 '18 at 07:06
  • how is serialization related to creation of object ? whatever i am passing should get saved right be it a new object or existing object ? – amit kumar Aug 23 '18 at 07:12
  • Because when you to `this`, you are basically passing the same object that you had passed, when calling the `writeObject` method in the first place, most probably in the `public static void main()`. But with the other code, you are again creating new object/reference of the same class leading to recursion – Ashishkumar Singh Aug 23 '18 at 07:38
  • If you move your `writeObject` code to your mail class, the error should dis-appear. Because now `Employee` class haven't overriden `writeObject` and so it will be called only once – Ashishkumar Singh Aug 23 '18 at 07:39
0

It is because of the fact that you are overriding writeObject method in your Employee class. So, when you create the Employee object and try to write it using writeObject method, it is called recursively leading to StackOverflow error.

But, when you do not write Employee object the code executes properly.

---Edit as per the clarification asked in comment

In your Employee class, you are overriding the writeObject method , so , whenever, you try to invoke ObjectOutputStream.writeObject with Employee as parameter, your overridden method will be invoked. Now in your overridden writeObject in Employee class, you are again calling ObjectOutputStream.writeObject( oos.writeObject(emp);) with Employee as parameter, thus, writeObject method of Employee class gets recursively called (with new Employee object everytime)and you get stackoverflow error.

Now in case when you try to call recursively this keyword, it is because of the fact that you try to invoke ObjectOutputStream.writeObject with the same instance of Employee class. As per the ObjectOutputStream.writeObject documentation at below mentioned link :

https://docs.oracle.com/javase/7/docs/api/java/io/ObjectOutputStream.html

Multiple references to a single object are encoded using a reference sharing mechanism so that graphs of objects can be restored to the same shape as when the original was written.

Infact, if you try the below code in your main method :

Employee emp = new Employee("sumit",10);
oos.writeObject(emp);
oos.writeObject(emp);

i.e if you invoke writeObject multiple times on same object, it is invoked only once.

codeLover
  • 2,571
  • 1
  • 11
  • 27
  • how is serialization related to creation of object ? whatever i am passing should get saved right be it a new object or existing object ? – amit kumar Aug 23 '18 at 07:16
  • Actually I wanted to understand why it doesn't call recursively when I pass this object to writeObject method: oos.defaultWriteObject(); oos.writeObject(this); – amit kumar Aug 23 '18 at 07:17