Why doesn't Serializable interface contain any methods? [duplicate] - java

This question already has answers here:
Although the Serializable interface in Java has no methods, no fields, it can achieve its function. How?
(6 answers)
Closed 7 years ago.
I know what is serialization and why it is used, but my question:
Why is serialization a marker interface?
What is the potential benefit of not having writeObject, readObject in Serializable interface because when we do serialization we finally override these 2 methods?
How does readResolve ensure that the object created during deserialization is not the new object. I know the below and it is returning the same object during deserialization but who will call this readResolve method internally?
private Object readResolve() throws java.io.ObjectStreamException {
return INSTANCE;
}

Because there needs to be some explicit way of declaring a class to be serializable. The framework can't just assume all classes to be serializable, as there are many kinds of objects that will stop working if their fields are written to disk and are later reloaded from there (e.g. FileInputStream, which relies on an open operating system file handle which might no longer exist when the object is deserialized). The modern way of having such a declaration would be an annotation, but those didn't exist in Java at the time serialization was added.
You won't necessarily need to override them - if the default behavior of the serializer is good enough; you don't need to do anything but implement Serializable.
The serialization framework calls it when an object has been completely deserialized. At this time, the object is allowed to inspect its own contents, and if it decides that it should instead be represented by another instance, it can return that instance instead (if not, it returns this). Whatever comes out of this method is returned to the code that requested the deserialization. If a preexisting object was returned, the new object created by the deserializer will not be seen by anyone and will eventually be garbage collected.

Marker Interfaces are used to tell JVM to perform specific tasks. they don't have any method. Serializable is also a marker interface.
Serialization is the process of flattening the objects. when you implement serializable interface in a class, it tells JVM to serialize its object i.e. it has to be converted into stream.

Related

Does Java have builtin ability or standard patterns for static deserialization?

Serialization makes sense as an instance method - an object might reasonably be able to serialize itself. An object should only ever be in a valid state, and all valid states of an object should be permissible to serialize. There is nothing invalid about this idea.
But deserialization does not make sense as an instance method. No part of an object's state should have any bearing on the process of constructing another object from data. There is no class foo such that you need a constructed foo in order to construct a foo.
So my question is, does standard java have a pre-existing set of interfaces/facilities to facilitate static deserialization? If you implement the instance-based approach, your deserialization "just works" (as much as anything does) with anything that works with Java's default deserialization ability.
Is there anything built in, to use classes as factories for objects of that class, constructed from serial data? Is there anything in Java I could pass a class to, such that this facility would know to call some static method to deserialize to construct an object from its flat form?
The deserialization instance method readObject is private. There is no way to call it from the outside. You could call it from one of your instance methods, but that would be very strange and I'd question why you'd be doing that in the first place. You say:
No part of an object's state should have any bearing on the process of constructing another object from data.
True, but I don't see why you think this would be an issue. There's no way you could call readObject from the outside (unless you call it from some other public method, which as I said, is kind of iffy) on an instance that you have already created. When you deserialize, you will most probably be using ObjectInputStream, which will use the no-args constructor to create a new instance, and then will hydrate that object using the data from the stream (when you call ObjectInputStream#readObject). So there is no question of the state of the instance affecting deserialization, because what you get back is an instance created from the serialized data (as Object, but you will then cast it to the concrete type).
In effect, readObject behaves somewhat like a constructor, except that it uses previously-serialized data to create an instance of an object. Extending the analogy, your question wouldn't make sense because you would be asking "Why does creating an object using the constructor have anything to do with the state of the instance?". The question of state doesn't even apply because you don't even have an instance! Similarly, state doesn't come into play with readObject because can never* deserialize and create an instance by using an existing instance.
If you want greater control over serialization, you can override readObject and writeObject from Serializable within your class if you want to handle things in a special way. You can exert greater control over how the data is written out by implementing Externizable and providing implementations for readExternal and writeExternal.
In your second question you're wondering what the "something" is that calls readObject. The "something" is reflection; ObjectInputStream will check to see if the class has a readObject method. If you've provided your own implementation, it will call that. Otherwise it will call defaultReadObject (which contains the logic for default serialization).
As far as built-in factories for deserialization, there isn't anything and I haven't really felt a need something since the standard serialization/deserialization approach seems to work well.
If you want more information on this, I suggest taking a look at the serialization specification for a comprehensive and in-depth view of how Java tackles serialization, and specifically Object Input Classes for your particular question.
*The only way state comes into it is if you do something strange like calling the readObject method from some other instance method (which would have to take in an ObjectInputStream), and then you have custom logic that performs deserialization based on the state of the existing instance. In other words, the only way the object's state has any bearing on deserialization logic is if you explicitly write it that way. Again, as I mentioned before, that would be very strange code, with a whole lot of caveats and of minimal value.

RMI serialization/marshal [duplicate]

This question already has answers here:
RMI marshal and serialization
(3 answers)
Closed 9 years ago.
I need some clarification on serialization in java. If i am serializing an object and i want to return that object over RMI do i just implement serializable on my object's custom class? I've seen objectoutputstream and objectinputstream but i don't know if i need to use those as i don't quite undersand their usage. My second question is how would i go about making an arraylist serializable? My third question is maybe related to my first question but how do i marshal an object before returning it? does serializing the object marshals it in the process?
Lets call the class in question Sentence:
public class Sentence implements Serializable {
}
And then i would be creating an instance of that class and returning that object from some other class
Yes: implementing Serializable makes your object serializable, unless it references an object that is not serializable. Object streams are used internally by RMI to send and receive objects. You don't need to use them if using RMI. If you want to send an object using sockets, or save it to a file, then you can use them.
ArrayList is already serializable. Look at its javadoc. You don't have to do anything.
You simply return the object from your RMI method, and RMI will serialize it for you. Serialization and marshalling are two words that basically mean the same thing. In the same way, if an RMI methods takes an argument, RMI will serialize the object passed as argument, send it to the RMI server, which will deserialize it and then call your actual method. It's all done for you by RMI.
Serializable is what's called a marker interface; it just tells Java that your class has some ability without requiring you to implement any particular methods. Implementing it in your class tells the JVM that it's okay (meaningful) to take the fields of your Java object and convert them to a packaged form for use later or on another computer.
That's all you have to do if all of the fields in your class are Serializable. If you have fields that aren't Serializable, such as fields that hold network connections or native resources, you'll need to mark them transient (ignored by serialization) and take care of setting them back up when your class is deserialized by overriding readObject and/or writeObject.

How does Externalizable differ from Serializable? [duplicate]

This question already has answers here:
What is the difference between Serializable and Externalizable in Java?
(11 answers)
Closed 9 years ago.
I read that
Externalizable provides us writeExternal() and readExternal() method which gives us flexibility to control java serialization mechanism instead of relying on Java's default serialization.
But If i implement Serializable and override readObject(), writeObject(), then does not it also means the same that I am customizing serialization process?
How does it differ?
THanks.
Difference between Externalizable and Serializable
In case of Serializable, default serialization process is used. while in case of Externalizable custom Serialization process is used which is implemented by application.
JVM gives call back to readExternel() and writeExternal() of java.io.Externalizalbe interface for restoring and writing objects into persistence.
Externalizable interface provides complete control of serialization process to application.
readExternal() and writeExternal() supersede any specific implementation of writeObject and readObject methods.
Though Externalizable provides complete control, it also presents challenges to serialize super type state and take care of default values in case of transient variable and static variables in Java. If used correctly Externalizable interface can improve performance of serialization process.
So go for Externalizable interface
When you have special requirements for the serialization of an object. For example, you may have some security-sensitive parts of the object, like passwords, which you do not want to keep and transfer somewhere. Or, it may be worthless to save a particular object referenced from the main object because its value will become worthless after restoring.
Official docs on Bean Persistence
Implement writeObject when you need to exercise greater control over what gets serialized when you need to serialize objects that default serialization cannot handle, or when you need to add data to the serialization stream that is not an object data member. Implement readObject to reconstruct the data stream you wrote with writeObject.
Use the Externalizable interface when you need complete control over your bean's serialization (for example, when writing and reading a specific file format). To use the Externalizable interface you need to implement two methods: readExternal and writeExternal. Classes that implement Externalizable must have a no-argument constructor.

Java serialization - java.io.InvalidClassException local class incompatible [duplicate]

This question already has answers here:
java.io.InvalidClassException: local class incompatible:
(10 answers)
Closed 3 years ago.
I've got a public class, which implements Serializable, that is extended by multiple other classes. Only those subclasses were ever serialized before - never the super class.
The super class had defined a serialVersionUID.
I'm not sure if it matters, but it was not marked private, but rather it just had the default protection - you might say it was package protected
static final long serialVersionUID = -7588980448693010399L;
The super class, nor any of the subclasses, however implemented readObject or writeObject, and none of the subclasses had an explicitly defined serialVersionUID. I figured one defined in the superclass would be sufficient.
Despite all this, things were fine as far as reading back previously serialized objects until a new instance variable, a List/ArrayList, along with a new method was added to the super class, and some private instance variables were added to one of its subclasses.
Now when trying to read back previously serialized objects, an exception is being thrown. One similar to this:
com.SomeCompany.SomeSubClass; local class incompatible: stream classdesc serialVersionUID = 1597316331807173261, local class serialVersionUID = -3344057582987646196
I'm assuming this is caused because the default serialVersionUID, which was used because I didn't declare one in any of the subclasses, has now changed due to the changes in the superclass and one subclass.
Suggestions on how to get out of this dilemma would be appreciated. I'm assuming I need to implement readObject and writeObject, but other than invoking defaultReadObject() and defaultWriteObject(), I'm not exactly sure what I need to do. Nor do I know if I need to add serialVerisonUIDs to all of the subclasses or if readObject and writeObject need to be implemented by each subclass, or if I can just implement them once, assuming I need to at all, in the superclass.
#DanielChapman gives a good explanation of serialVersionUID, but no solution. the solution is this: run the serialver program on all your old classes. put these serialVersionUID values in your current versions of the classes. as long as the current classes are serial compatible with the old versions, you should be fine. (note for future code: you should always have a serialVersionUID on all Serializable classes)
if the new versions are not serial compatible, then you need to do some magic with a custom readObject implementation (you would only need a custom writeObject if you were trying to write new class data which would be compatible with old code). generally speaking adding or removing class fields does not make a class serial incompatible. changing the type of existing fields usually will.
Of course, even if the new class is serial compatible, you may still want a custom readObject implementation. you may want this if you want to fill in any new fields which are missing from data saved from old versions of the class (e.g. you have a new List field which you want to initialize to an empty list when loading old class data).
The short answer here is the serial ID is computed via a hash if you don't specify it. (Static members are not inherited--they are static, there's only (1) and it belongs to the class).
http://docs.oracle.com/javase/6/docs/platform/serialization/spec/class.html
The getSerialVersionUID method returns the serialVersionUID of this
class. Refer to Section 4.6, "Stream Unique Identifiers." If not
specified by the class, the value returned is a hash computed from the
class's name, interfaces, methods, and fields using the Secure Hash
Algorithm (SHA) as defined by the National Institute of Standards.
If you alter a class or its hierarchy your hash will be different. This is a good thing. Your objects are different now that they have different members. As such, if you read it back in from its serialized form it is in fact a different object--thus the exception.
The long answer is the serialization is extremely useful, but probably shouldn't be used for persistence unless there's no other way to do it. Its a dangerous path specifically because of what you're experiencing. You should consider a database, XML, a file format and probably a JPA or other persistence structure for a pure Java project.
For me, I forgot to add the default serial id.
private static final long serialVersionUID = 1L;
This worked for me:
If you wrote your Serialized class object into a file, then made some changes to file and compiled it, and then you try to read an object, then this will happen.
So, write the necessary objects to file again if a class is modified and recompiled.
PS: This is NOT a solution; was meant to be a workaround.

what is serialization and how it works [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Why Java needs Serializable interface?
I know the serialization process but have't implemented it.
In my application i have seen there are various classes that has been implemented serilizable interface. consider following class
public class DBAccessRequest
implements Serializable
{
private ActiveRequest request = null;
private Connection connection = null;
private static Log log = LogFactory.getLog(DBAccessRequest.class);
public DBAccessRequest(ActiveRequest request,Connection connection)
{
this.request = request;
this.connection = connection;
}
/**
* #return Returns the DB Connection object.
*/
public Connection getConnection() {
return connection;
}
/**
* #return Returns the active request object for the db connection.
*/
public ActiveRequest getRequest() {
return request;
}
}
just setting request and connection in constructor and having getter setter for them.
so what is the use of serilizable implementation over here...
It's what is called a marker interface; it's used to define types that are serializable in Java. From the API:
java.io.Serializable: Serializability of a class is enabled by the class implementing [this] interface. Classes that do not implement this interface will not have any of their state serialized or deserialized. All subtypes of a serializable class are themselves serializable. The serialization interface has no methods or fields and serves only to identify the semantics of being serializable.
See also:
Wikipedia/Marker interface pattern
Effective Java 2nd Edition, Chapter 11: Serialization.
Also Item 37: Use marker interface to define types.
Sun Developer Network Technical Article/Discover the secrets of the Java Serialization API
Layman would say : "Serializable? It's how to tell Java, that I need to breake this object to bytes and safely store somewhere else, and vice versa"
Serialization is more complicated then that, if you ever tried to save a few native variables like int, long, etc. into a stream you called them literally.
int i=100;
stream.write(i);
The thing about serialization, every Serializable object has a serialVersionUID that is unique to each object that is Serializable, and via reflection + a very sophisticated mechanizem (to prevent saving the same instance of an objects over again) it breaks down the object and saves it as bytes, just like my example, only there is a predefined very general mechanizem that does it.
which means, in your example it would look into the DBAccessRequest Class object check for which variable are there and if they are Serializable too it would perform the same process on them, and chop them to their Serializable core, and save them as bytes.
This is all metaphorical to explain the general concept of a process which is very complicates, very intresting and worth investigating (you should look it up also):
How Serialization works1
How Serialization works2
Hope this help,
Adam.
From Sun:
We all know the Java platform allows
us to create reusable objects in
memory. However, all of those objects
exist only as long as the Java virtual
machine1 remains running. It would be
nice if the objects we create could
exist beyond the lifetime of the
virtual machine, wouldn't it? Well,
with object serialization, you can
flatten your objects and reuse them in
powerful ways.
So I think that the reason why this is marked as serializable was that once that the JVM is up and running again, the data that was previously used is loaded and used again. This might be useful so as to avoid having the user enter the same data each and every time that the application loads.
Rozer, I guess you mean why the class is marked Serializable and no functionality related to serialization is put there except getters and setters.
The class might not directly implement the serializable functions.
The class which derives your DBAccessRequest class might implement them; or
The class which has an instance of DBAccessRequest might needed to be serialized which necessitate DBAccessRequest to be serializable.
I don't have any other explanation for this.

Categories