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
Java Linkedhashmap Get First or Last Entry
Stand-Alone Java Code Formatter/Beautifier/Pretty Printer
Gradle: Could Not Determine Java Version from '11.0.2'
Lambda Expression to Convert Array/List of String to Array/List of Integers
Should I Call Ugi.Checktgtandreloginfromkeytab() Before Every Action on Hadoop
How to Import Spring-Config.Xml of One Project into Spring-Config.Xml of Another Project
Dynamically Change Spring Data Source
How to Get Absolute Path to File in /Resources Folder of Your Project
Java:Parse Java Source Code, Extract Methods
Getting Java.Lang.Classnotfoundexception: Org.Apache.Commons.Logging.Logfactory Exception
Consistency of Hashcode() on a Java String
Java 8 Streams Flatmap Method Example
Adding in Clause List to a JPA Query
How to Load a Large Xlsx File with Apache Poi
Java: Random Long Number in 0 <= X < N Range