I faced this question in an interview. Please help me to find the answer. The question was Can a transient variable be serialized in any way?
static and transient fields are not serialized by default.
However they can be serialized if
the same object is accessible via a serialized field.
the object is serialized in a readObject/writeObject or readExternalizable/writeExternalizable.
you are using a different serialization library with different rules (I don't know any which serializes static fields, though I have written such a library by mistake once)
Usually a field is made transient to mean it shouldn't be serialized, though sometimes it might be because
the type is not Serializable
you don't want to use the default Serialization.
Recently in an interview I was also asked this question and here what I answered
Yes, transient member can be serialized. We need to do following to acheive same:
Make your non-serialisable field transient
In writeObject(), first call defaultWriteObject() on the stream to
store all the non-transient fields, then call other methods to
serialize the individual properties of your non-serializable object.
In readObject(), first call defaultReadObject() on the stream to read
back all the non-transient fields, then call other methods
(corresponding to the ones you added to writeObject) to deserialise
your non-serializable object.
Related
I have a class which contains nio buffer as a data member. I am wonderign how to serialize this class?
Make it transient so it is not serialized by default. If you need to serialize the dat in it you can add your own writeObject and readObject methods to do this.
Are you asking how to prevent a specific field from being serialized when implementing Serializable? If so, make the field transient.
If I have an instance of a class that I store in a session I need to make it serializable. This class has a static variable, will this be serialized in every instance stored?
The static variable is a reference to a cache containing a lot of data in the background. Will all of this data be serialized? If so, it seems preferable to make this variable transient and re-fetch the cache instance each time the instance is restored. Maybe not store the cache instance at all in the class.
Will the constructor execute when a class is restored from a serialized state? if not is there any other method I can use to re-instate a transient variable?
This class has a static variable, will
this be serialized in every instance
stored?
No. According to the Java Object Serialization Specificaiton: "Default serializable fields of a class are defined to be the non-transient and non-static fields."
Will the constructor execute when a class is restored from a serialized state?
No. Deserialization bypasses constructors (unless you have a non-serializable superclass).
if not is there any other method I can use to re-instate a transient variable?
You can use the readObject() method for that, as described in the Serializable API doc.
static and transient fields are not serialized. No, the constructor is not called. For more details, please check this out: http://java.sun.com/developer/technicalArticles/ALT/serialization/
Serialization is a mechanism of storing the state of an object. Based on this definition we can say that the instance variables in an object can be serialized.
Methods are behaviors of the class.
We can set and get the state of an object using the methods. So the methods are related to the instance variables of the class.
Then why can't we serialize the methods in Java ?
What do you plan on 'after' serializing the methods? The state of the object has to be by definition should be only its members. Their behaviors would not come into picture. And serialization is saving the state of the object and not its behaviors.
Methods are always serialized: as bytecode in a class file. There is no practical need to serialize them again.
From OOP perspective, the state of an object is the total state of its non-static fields. Methods are a way to define the object behaviour and are common to all instances (objects) of that class, so they are defined as fields at the Class object not as a field of the object (instance) itself. So serializing the object would store its state thus only its fields, but if you serialize the Class object of your objects you would be serializing the methods of those objects (thought I see no reason why would someone bother himself to do so).
Because method the same for all instances of class, they only driven by its data. If you have class definition in your app - you have it's methods.
But data can change from instance to instance.
A method per say does not have any state, and a serialized method call cannot be used for anything. On the other hand, a serialized thread is conceptually a snapshot or checkpoint of a computation, and that would be useful.
However, threads are not serializable in Java, and it would be really difficult to implement this. (For example, how would you cope with the case where the code of one of the active methods was changed between serializing and deserializing a thread?)
Can a transient field in a class be obtained using reflection? (using getDeclaredField(..))
Yes, It is a normal field. You can check whether it is transient by:
Modifier.isTransient(field.getModifiers());
transient:
A keyword in the Java programming language that indicates that a field is not part of the serialized form of an object. When an object is serialized, the values of its transient fields are not included in the serial representation, while the values of its non-transient fields are included.
So no logical reason for it not to be accessible by reflection. It's the value of the field that is ignored (sometimes), not the field itself.
(btw, what hindered you from just trying to call getDeclaredField("yourTransientField")?)
transient indicates that the field will not be serialized. The field is still declared by the class, so it is fair game for reflection.
Among all the objects that needs to be serialized there are those one that need not to be serialized. That's why this objects are marked with the keyword transient.
transient fields have nothing to do with reflection. The keyword only signals that a field should be skipped during Java serialization process. So reflection can access transient fields just like any other fields.
I was using the Mersenne-Twister implementation at http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/VERSIONS/JAVA/MTRandom.java as a drop-in replacement for the default java.util.Random class. However, four fields (an int, a boolean and two byte[]) are marked as transient. This means that I can't serialize an object of this class without implementing custom functionality.
The question is, is there any reason that these fields are marked transient? Is there any code in there that holds information that won't make any sense when the object is read in from a file? I removed the transient modifier from the fields and it seems to work fine, but I haven't tested it intensively and so might there be cases where it breaks?
Personally, I can't see why, since all that's done in the class is arithmetic.
From the comment on serialVersionUID, it looks like the author didn't want to consider serialisation. Adding transient may have suppressed some compiler/IDE warnings.
Most likely the reasoning behind making all of the non-static fields of the class transient was so that the MTRandom class stays binary compatible with java.util.Random, from which it is extended.
So theoretically, you could serialize an MTRandom instance, and deserialize it as a Random instance and everything would work.
If those fields aren't transient, then they would be serialized and become incompatible.
However, as far as I can tell, removing the transients shouldn't cause a problem for you.