wood burning stoves*
The moose likes Java in General and the fly likes Customize readObject and writeObject Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Customize readObject and writeObject" Watch "Customize readObject and writeObject" New topic
Author

Customize readObject and writeObject

Wilson Oak
Greenhorn

Joined: Apr 21, 2005
Posts: 19
hi all, I have following code testing customized readObject and writeObject methods in serialize class.



The output is:
from Dog.writeObject: name=1 dogNum=100
from Dog.readObject: name=0 dogNum=0
from main: name=0 dogNum=20


Can anyone tell me why the Dog object d returned from readObject() has dogNum=0 instead of 100 as dogNum has been set to 100 before it was written to file.

Thanks,


~WOak
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18545
    
  40


You should not be calling writeObject(this) inside your serializable object's writeObject method. Almost anything else is fine, but not itself. After all, that was what triggered the write in the writeObject() call in the first place.

You are attempting to do a recursive call, which will hit the serialization code to prevent such a thing. And since you actually never explicitedly wrote the data... regardless, if you just want to use the default serialization, use the defaultWriteObject() (and defaultReadObjet()) methods instead.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Naman Patidar
Greenhorn

Joined: Oct 03, 2008
Posts: 15
You should call defaultWriteObject() to write/serialize the complete current object, instead of calling writeObject(this) from custom writeObject().
Or you can use various writeDataType() methods to write/serialize individual members.
and similar with read part as well.

also you have to make Animal class serializable to serialize it's state.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19655
    
  18

No you don't. Because it has a non-parameter constructor this will be called instead. You can see it if you add a constructor:
It does mean that num will not be serialized; that's why even with defaultWriteObject / defaultReadObject it will remain 0. It should be serialized manually:

Wait, I misread your post. You are right, to (automatically) serialize Animal's state you must make Animal Serializable as well. The above can be used for non-final fields if it's not possible to make the super class Serializable (because it's from the core API or a third party library).


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Vinoth Kumar Kannan
Ranch Hand

Joined: Aug 19, 2009
Posts: 276

Wilson Oak wrote:
public class Test {
public static void main(String[] args) throws Exception, IOException {
Dog obj = new Dog();
obj.num = 1;
obj.dogNum = 2;

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("test"));
oos.writeObject(obj);
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test"));
System.out.println("from main: " + ois.readObject());
}
}


I dont understand this...with just calling ObjectOutputStream's writeObject and ObjectInputStream's readObject, mustn't the output just be num = 1 & dogNum = 2 ?? I seriously am not getting this..


OCPJP 6
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18545
    
  40

Vinoth Kumar Kannan wrote:
I dont understand this...with just calling ObjectOutputStream's writeObject and ObjectInputStream's readObject, mustn't the output just be num = 1 & dogNum = 2 ?? I seriously am not getting this..


Not all objects are serializable. Not all objects are serializable correctly. In this case, the class provides readObject() and writeObject() methods, which will be called during serialization, which incorrectly serializes the object.

Henry
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19655
    
  18

Because Animal isn't Serializable num is never serialized automatically. As said before, to include num you must either make Animal Serializable or handle it yourself like my code has shown.
Vinoth Kumar Kannan
Ranch Hand

Joined: Aug 19, 2009
Posts: 276

Henry Wong wrote:
Not all objects are serializable. Not all objects are serializable correctly. In this case, the class provides readObject() and writeObject() methods, which will be called during serialization, which incorrectly serializes the object.


The Serializable interface defines no methods on its own. Then how come it is automatically going to call readObject() and writeObject() private methods on serializing?
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18545
    
  40

Vinoth Kumar Kannan wrote:
The Serializable interface defines no methods on its own. Then how come it is automatically going to call readObject() and writeObject() private methods on serializing?


That's how the serialization mechanism works. The readObject() and writeObject() methods are optional. The methods are private (which you noticed). And if they exist, it will be called to handle serialization (just for that, and not the super) of the class.

Henry
Wilson Oak
Greenhorn

Joined: Apr 21, 2005
Posts: 19
Henry, thanks so much for explaining stuff.

Why do I do that? because I have been told during interview that developer should create a custom writeObject() and readObject() in order to make serialization more effectively. For example, let's say there is an object needed to be serialized thru the network, we should only serialize its useful value but not implementation value (i.e. hash code, index).

I am not sure what did that guy mean, and also I don't know the different between the way he mentioned and using transient.

What is the best practice to optimize serialization?
Naman Patidar
Greenhorn

Joined: Oct 03, 2008
Posts: 15
Hey everyone,
wilson here I am posting a correct solution for your program, which is using defaultWriteObject(), which does nothing but doing the same thing done by default writeObject() :-


Now here are custom overrided methods which I guess you want to implement :-


Now for which approach is better... ?
It depends upon your needs. If you need complete object to be serialized than default implementation provided is better and optimized. and if you want some of the values from object than go for custom implementation.
Hope it will help.
Wilson Oak
Greenhorn

Joined: Apr 21, 2005
Posts: 19
Naman, thanks. It makes more sense right now.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Customize readObject and writeObject
 
Similar Threads
Externalizable and null values in read/writeExternal
about private void writeObject ( ObjectOutputStream os )
Serialization Code
How Inheritance Affects Serialization
Clarification on concepts for Serialization