You can think of Serializable as a flag that tells Java that the instance variables in your class can be serialized. That is, when your class is written out to a file or to a socket, the value of the instance variables are passed along. If the class is not Serializable then the instance variables are set to their default values based on the default constructor of the class.
Originally posted by Dale DeMott: What exactly does Serialiable do for you? I've seen it used but not sure of its uses. What are the advantages and disadvantages of it. -D
Oh wow! Serialization is, in my very humble cowgirl opinion, THE coolest thing in all of Java. It was the biggest treat when it came out with 1.1 (not available in 1.02, which very much depressed me). Serialization in Java is known in general OO terms as "object flattening" or "object persistence". I came from a game development background, and in order to "Save Game", we had to write what we called 'spill your guts' methods into each class. Those methods would be called and each object would faithfully write out it's own instance variable state. YUCK! Well, even if *that* isn't so bad, imagine what happens if you accidentally get your own protocol wrong (and since without Serialization you'd be on your own for a protocol) and then you try to *restore* (essentially de-serialize) the state of the objects. You have to know the order in which you wrote out each and every instance variable, so that you can bring everything back to life. It was very, very ugly. With serialization in Java, it takes a couple lines of code and you've written not just a single object -- but the entire object *graph* for that object. In other words, the instance variables in the object... and if those instance variables are object references -- then it means the objects at the other end of those references have to be written. And, well, that means the instance variables of *those* objects have to be written. Objects all the way down. It is like magic, how clean and easy. Best of all, if something goes wrong, you will NOT be able to restore an object *partially*. It either restores (deserializes) correctly or it throws an exception. So you don't end up with objects that look like they've come from a bad Star Trek transporter accident. Best, best of all: Without Serialization, how easy would it be to do RMI? Jini? For that matter, EJB? Serialization is the way in which distributed objects (in other words, two objects running on different virtual machines -- usually different *physical* machines as well) pass arguments and return values. And since it is a common protocol, you don't even have to do the serialization yourself when you use RMI, Jini, EJB, etc. Serialization lets objects -- real live objects -- move over the network. So you're not just passing data, you're passing real honest-to-goodness objects. They get flattened, shipped, and reanimated on the other side, almost transparently. DISADVANTAGES: *The class must be marked serializable, and the instance variables you want to save must be marked serializable. (Although it's usually fairly trivial to serialize an object even if it DOES have a non-serializable instance variable). *That object graph could be HUGE. May not be a problem if you're using serialization for persistence, in other words, to save an object to disk or an object database. But if you're using serialization to ship objects over the network, then you DO care, and you might have to get involved. Fortunately, there are mechanisms in serialization that let you easily step into the middle of the flattening/unflattening (i.e. serialize/deserialize) process to tweak it for your needs. *Not a speed demon, although virtually all business apps are far more likly to be slowed down by bandwidth issues anyway, as opposed to being slowed down by the overhead of serialization and deserialization. * The class MUST be present and accessible to the VM trying to deserialize the object. No problem for anything in the core library, otherwise you have to get the class to the "client". But... since technologies like Jini would never work if you had to KNOW who all your potential clients were, there is a fabulous mechanism in RMI called dynamic class downloading that lets you do the following: *ship an object over the network via RMI, say, an object that you're sending as the return value of a remote method call. * now imagine the calling client code (the code that invoked the remote method) is written to use an interface type, so that it doesn't specify which actual class your object is instantiated from. * No problem until the client VM tries to deserialize the object so that you can get a full, live, breathing object as that return value. At *this* point, the client had better have the class. But wait! The serialized object is shipped with a little label that says, "Hello. Here is where my class lives... you'll find it by doing an http 'get' on this URL here." So even if the class is NOT on the client, it will then be AUTOMATICALLY fetched, loaded, and the deserialization can continue un-noticed to the client. It takes VERY little effort to set up dynamic code downloading, and it allows the ultimate in flexibility and maintability, extensibility -- all those good 'ilities'. Whoops, before I go any further in evangelism land, I just realized that we're in the Threads forum. This belongs on the Distributed forum (Michael Ernest's forum, guru of all things distributed). Maybe someone who knows how will move this But you just had to get me going...
Well, I have a question. I come with a Python Background and in Python, the Pickler or cPickle would handle the dumping of object to HDD. In Java, the same is taken care of by the object ( which is of type Serialisable ) Why this?? Of what I remember of Python, we dont have to implement or extend a fancy class, just to enable it to be written to file. More so, the dumping in Java can also be done programatically, by writing our own method to write the object state to a file. Why "Serialisable" then?? I understand the uses of Serialisable.. as mentioned in the above post. Regds Lupo
Pickling is the Python (and Jython) version of serializing. They're extremely similar. A Pickler is like an ObjectOutputStream; an Unpickler is like an ObjectInputStream. In both languages the objects do assume some of the work of (de)serializing/(un)pickling. In Python an object's __getstate__ method is invoked when it's pickled; in Java the writeObject(ObjectOutputStream) method is called on an object being serialized. Likewise when unpickling/deserializing it's __setstate__ and readObject(ObjectInputStream) respectively. In all cases you don't actually have to implement these yourself unless you wish to override the default serialization/pickling behavior provided by the languages. I just bring them up to note that in both languages the object being serialized is in fact involved in the serialization process. The main difference between the two languages here is that in Python, user-defined classes are picklable by default. If you don't want them pickable, you can define __getstate__ and __setstate__ to raise a PicklingError. In Java, classes are not serializable by default - you must add "implements Serializable" to the declaration if you want this feature. Not a big deal. This is consistent with some of the general differences between the languages - Python is more likely to assume details that you leave out, and Java is more likely to throw an error to let you know if you didn't define something correctly. [ January 07, 2003: Message edited by: Jim Yingst ]
"I'm not back." - Bill Harding, Twister
Joined: Dec 01, 2000
Thanks Jim! That sure explained it all!! Well, I had a fair idea about the serialisation and pickling.. but it has now been hardened by you. I have a clearer pic. now. Well, thats what I do not understand. Why would the object need to be of type *serialisable* to make it a candidate for persistance. But you just gave the answer that it is for consistency.. well, thats understandable. Thanks again. Regds Lupo
In Effective Java Programming Language Guide, Joshua Bloch wrote many thoughts about serialization. I think the intention can be summarized as "Implement Serializable judiciously." Maybe I am wrong, but I think to have read somewhere that Java at its origins was based on a language that was destinated to embedded systems. In that "Java" all objects were serializables by default. With the advent of Java as the ultimate Internet language, that all objects could be transported anywhere to the world was thought as insecure. Nowaydays a class must explicitly confirm that is suitable to be serialized. Anyway, some of the precautions exposed by Joshua are: A) If you do not got to the effort to design a custom serialized form, but merely accept the default, the class's private and package instance fields becomes part of its exported API. In this way, it decreases the flexibility to change a class's implementation once it has been released. B) Serial versions UIDs are automatically generated based on the name of the class, the names of their interfaces, and of all public and protected members. If a change is made to the class but you do not provide a custom serial UID the compatibility will be broken. C) Serialization is a extralinguistic mechanism, deserialization is a hidden constructor. All the invariants for an object should be checked in the process of deserializing an object, as a constructor would do. D) Classes design for inheritance should rarely implement serializable. Doing otherwise places a burden into the programmer extending the class. E) Inner classes should rarely implement Serializable. Their synthetics fields and names are not especified. F) The default serialization process deals with the physical representation of an object. It also describes the topology of the objects referenced from the object to be serialized. But what is really important to serialize is the logical data of the object. G) Disavantages of using the default serialization when the physical representation of an object difers greatly form the logical: G1) It permanently ties the exported API to the internal representation G2) It can consume excessive time or space G3) it can overflows. H) A stream of bytes to be deserialized could have been tampered with to change the immutability of an object, or to provide references to private data. This is a security risk. To avoid it, checks the validity (invariants) of the deserialized object within the readObject method. Also is critical to defensively copy any field containing an object reference that a client must not posses. I) Typesafe enum and singletons should use readResolve to ensure their characteristics when deserialized.
SCJP2. Please Indent your code using UBB Code
Joined: Dec 01, 2000
thanks Jose!! That was really helpful!! Regds Lupo