This question is about ObjectInputStream and how it builds fields declared as transient. Considering a simple use-case of ObjectInputStream
FileInputStream fis = new FileInputStream("t.tmp");
ObjectInputStream ois = new ObjectInputStream(fis);
SomeClass sc = (SomeClass) ois.readObject();
Where SomeClass is
class SomeClass {
int x;
transient OtherClass y;
}
class OtherClass {
int z;
}
what will be the value of sc.y after ois.readObject ?
I am asking to clarify what i read at docs.oracle.com which states
"Fields declared as transient or static are ignored by the deserialization process. References to other objects cause those objects to be read from the stream as necessary."
What does it mean that transient fields are ignored? And how can they be read from the stream if they are transient (ie not serialized - how i understand it...)
Matthias
what will be the value of sc.y after ois.readObject ?
Someclass.y
will be the "default value". In this case, since it's an object, it will be null
.
What does it mean that transient fields are ignored?
They're not serialised - they're skipped. From the Java Object Serialisation Specification:
A Serializable class must do the following:
- Implement the java.io.Serializable interface
- Identify the fields that should be serializable (Use the
serialPersistentFields
member to explicitly declare them serializable or use thetransient
keyword to denote nonserializable fields.)
... and ...
The easiest technique is to mark fields that contain sensitive data as
private transient
. Transient fields are not persistent and will not be saved by any persistence mechanism. Marking the field will prevent the state from appearing in the stream and from being restored during deserialization. Since writing and reading (of private fields) cannot be superseded outside of the class, the transient fields of the class are safe.
And your next question:
And how can they be read from the stream if they are transient
They're not in the stream - so, actually, they're not read. As mentioned above, the end up as the 'default value' for that type (null
for objects, 0
/false
for primitives).
"Fields declared as transient or static are ignored by the deserialization process."
For the most common case, they're ignored by the serialisation process - and because of that, they're not in the stream, and won't be deserialised. However, if you changed the class subsequent to serialising the object so that a field that used to be serialised is now marked as transient, then the deserialisation process will ignore that value when it finds it in the stream.