Serialization - Readobject Writeobject Overrides

Serialization - readObject writeObject overrides

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).

Custom Serialization using ReadObject and WriteObject

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.

How much should I override readObject() writeObject(), in java?

void writeObject (ObjectOutputStream out) throws IOException{
out.writeObject(familyName);
out.writeObject(name);
}
void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
familyName = (String) in.readObject();
name = (String) in.readObject();
}

void writeObject (ObjectOutputStream out) throws IOException{
out.writeObject(name);
}
void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
name = (String) in.readObject();
}

It doesn't matter in the least what you put into these methods as posted, because none of them is ever called. They aren't private, as required by the Object Serialization Specification, so Serialization doesn't call them.

And given that they are supposed to be private, using @Override is futile as well.

As your code presumably works, you can conclude from that alone that you don't need to do this at all. Let Serialization do it for you.

De-/Serializing with readObject/writeObject

The above actually seems to work.

The problem appears to have been that I had overlooked a val using file. Changing that val to a def allowed me to serialize SourcePosition

Exceptions allowed while implementing readObject and writeObject method to override default serialization in java?

Serializable defines the following exceptions:

private void writeObject(java.io.ObjectOutputStream out)
throws IOException
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException;
private void readObjectNoData()
throws ObjectStreamException;

This is where the write method gets called:

        try {
writeObjectMethod.invoke(obj, new Object[]{ out });
} catch (InvocationTargetException ex) {
Throwable th = ex.getTargetException();
if (th instanceof IOException) {
throw (IOException) th;
} else {
throwMiscException(th);
}
}

// ...

private static void throwMiscException(Throwable th) throws IOException {
if (th instanceof RuntimeException) {
throw (RuntimeException) th;
} else if (th instanceof Error) {
throw (Error) th;
} else {
IOException ex = new IOException("unexpected exception type");
ex.initCause(th);
throw ex;
}
}

As you can see you can throw any non-runtime exception and it will be wrapped in an IOException, though you should prefer IOExceptions due to shorter stack traces and more useful error messages.

I assume the read method gets called similarly, you might want to check it yourself though.



Related Topics



Leave a reply



Submit