aspose file tools*
The moose likes Java in General and the fly likes Serializable in inheritance Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Serializable in inheritance" Watch "Serializable in inheritance" New topic
Author

Serializable in inheritance

senthil rajan
Ranch Hand

Joined: Aug 31, 2005
Posts: 36
Hi Frnds,

If the Parent class implements Serializable, the Child class also eligible for Serialization by default. In my case, I need to remove the serializable funtionality from the Child class. What should i do?

Can I get any idea on this?

Thanks,
Senthilrajan.
William Brogden
Author and all-around good cowpoke
Rancher

Joined: Mar 22, 2000
Posts: 12781
    
    5
My guess is that your derived class should have a writeObject method that throws NotSerializableException. Probably the same for readObject.
I think that is what the javadocs for the java.io.ObjectOutputStream imply.
Bill
ramprasad madathil
Ranch Hand

Joined: Jan 24, 2005
Posts: 489


Originally posted by William Brogden
------------------------------------------
My guess is that your derived class should have a writeObject method that throws NotSerializableException. Probably the same for readObject.
------------------------------------------


Well, I think thats about the only way with the caveat that your subclass should implement Externalizable in which case the writeObject and readObject would be called on your implementation (in the subclass).

In another words, if your class doesnt implement Externalizable and you have writeObject and readObject methods, they would be quite redundant. Then, on serialization, the writeObject and readObject methods of the ObjectOutputStream and ObjectInputStream respectively are the ones which are invoked. And since your parent class implements 'Serializable', there wouldnt be exceptions thrown.

Another roundabout method would be to define subclass variables as transient.

cheers,
ram.
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
As long as you have not violated the rule of "all public methods on an interface", you can solve your issue by simply declaring your new implementation type by using delegation. Avoid concrete inheritance always. At times you must concede simply because you are dependant on an API that mandates it (the obvious example is the one called the J2SE API Specification i.e. all Java classes must use concrete inheritance implicitly), so unless you're prepared to rewrite your dependancies, at least make informed decisions regarding the brokenness and recognise the optimal point to concede.

Given:
interface X{void m();}
and:
// note here that I do not condone non-private constructors,
// but have done so for brevity.
final class XImpl implements X, Serializable{public void m(){}}

You can rewrite your new implementation properly using:
final class AnotherX implements X{private final X x;{x = new XImpl();}public void m(){x.m();}}

You should also note that an interface that declares no methods, and at the same time does not inherit from two or more interfaces, is an implicit requirement defect. e.g. java.io.Serializable. Interfaces should not be (ab)used as metadata, but for specifying contractual behaviour.
[ August 31, 2005: Message edited by: Tony Morris ]

Tony Morris
Java Q&A (FAQ, Trivia)
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24184
    
  34

Originally posted by ramprasad madathil:

In another words, if your class doesnt implement Externalizable and you have writeObject and readObject methods, they would be quite redundant. Then, on serialization, the writeObject and readObject methods of the ObjectOutputStream and ObjectInputStream respectively are the ones which are invoked. And since your parent class implements 'Serializable', there wouldnt be exceptions thrown.


As it turns out, this is not true at all. ObjectOutputStream will indeed call writeObject() if a Serializable class supplies it. It is not necessary to use Externalizable. What Externalizable does is make your class responsible for storing the superclass state as well -- otherwise your writeObject() is expected to save only the most derived class's state.

To back up what Bill said, here's a quote from the Tiger Javadoc for ObjectOutputStream:


Serialization of an object can be prevented by implementing writeObject and readObject methods that throw the NotSerializableException. The exception will be caught by the ObjectOutputStream and abort the serialization process.


Finally, I sympathize with what Tony says, but I don't necessarily agree. Nothing prevents an abstract class from implementing Serializable, or an interface from extending it. Then you're stuck, and there's no concrete inheritance involved.


[Jess in Action][AskingGoodQuestions]
sever oon
Ranch Hand

Joined: Feb 08, 2004
Posts: 268
Don't extend a class that implements Serializable if you don't want the child class to adhere to that contract as well.

One way to fix this would be to change the parent class. It could provide a final (so that it is non-virtual) method that hands back a serializable wrapper around itself (much like the way Collections hands back wrappers around maps that synchronizes them). Then subclasses are not required to be serializable.

Another approach is to have the child class aggregate an instance of the parent class, duplicate its API and forward the methods. That way, this new class does not have the parent in its hierarchy and claim to meet its contract.

Ironically, one approach you should *not* follow is very similar to the approach I recommended above. Like synchronization, the Collections API in the JDK provides a means of making a map (and other collections) unmodifiable by wrapping them so that methods that cause modifications throw UnsupportedOperationExceptions. This is terrible, and you should definitely not extend a parent class that is serializable and then start throwing these exceptions too.

Think about it...I write a method that takes in a Foo, which is Serializable. You extend Foo with Bar, a class that throws Unsupported OperationExceptions. Then you instantiate a Bar and hand it into my method that takes a Foo. This, of course, works just fine--polymorphically, you've made Bar so that it *is* a Foo.

But then my method, which has every right to expect the passed object to be serializable, gets a nasty surprise when it tries to serialize it. This is not the way to code.
ramprasad madathil
Ranch Hand

Joined: Jan 24, 2005
Posts: 489


Originally posted by Ernest

As it turns out, this is not true at all. ObjectOutputStream will indeed call writeObject() if a Serializable class supplies it. It is not necessary to use Externalizable. What Externalizable does is make your class responsible for storing the superclass state as well -- otherwise your writeObject() is expected to save only the most derived class's state.


I did not know that. Thanks

cheers,
ram.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Serializable in inheritance