Transient keyword:
When we have a class which implements Serializable interface,
that means its eligible for getting serialized but we want few fields not to get
serialized then we can place the transient keyword before their declarations to
tell the serialization mechanism that the field should not be saved along with
the rest of that object's state. Then those transient fields will not be
serialized. That means their values will not be saved into bytestream while
serialization and when deserialization, those transient fields will be stored back
into the object with their default values.
For example,
If we put transient keyword in the fields’ declarations
of the TestObject class like below:
TestObject.java
package Serialization;
import
java.io.Serializable;
public class TestObject implements Serializable {
transient int number;
transient String name;
TestObject(int i, String s) {
number = i;
name = s;
}
}
If you compile and run ‘SerializationTest.java’, you will
get the following output:
Number: 0
Name: null
Here, the field ‘number’
is a date type of integer and hence its value is stored as int default value ‘0’
and the field ‘name’ is a date type of String
and hence its value is stored as String default value ‘null’.
Can we serialize
static fields?
No, we can’t serialize static fields as static fields belong
to class not to any object. There is only a single copy of static field values and
all objects share these values. If any object modifies the static field value then
that modified values will be seen by all other remaining objects of that class
which contains the static field.
For example, If we put static keyword in the name field declarations
of the TestObject class like below:
TestObject.java
package Serialization;
import
java.io.Serializable;
public class TestObject implements Serializable {
int number;
static String name;
TestObject(int i, String s) {
number = i;
name = s;
}
}
If you compile and run SerializationTest.java, you will get
the following output:
Number: 10
Name: TestSerialization
Ooh… still gets the value for our static field name after deserialization and seems
contradictory to my statement??
NO. Don’t get confuse
here. Actually here the value of name
field is taken from class (TestObject) not from deserialized object (tObj2). The static field name of TestObject gets value “TestSerialization” when the creation
of tObj1 object in main() method of SerializationTest class
TestObject tObj1 = new
TestObject(10, "TestSerialization");
Like we are told, only one copy of static fields will be there
and shared by all other objects. So while creation of tObj1 object, the static
field name has been initialized with
the value “TestSerialization” and that is persisted and visible to all other objects.
So it’s also visible to the object tObj2 and hence the value of name is getting
printed as “TestSerialization”.
So If you create an object tObj3 just before printing the
deserialized object values in the main method of SerializationTest as like
below:
SerializationTest.java
package Serialization;
public class SerializationTest {
public static void main(String[] args)
{
TestObject
tObj1 = new TestObject(10, "TestSerialization");
SerializeUtility
utility = new SerializeUtility();
// serialization
utility.serialize(tObj1);
// deserialization
TestObject
tObj2 = (TestObject)utility.deSerialize();
TestObject
tObj3 = new TestObject(100, "NoStatic");
System.out.println("Number:
" +
tObj2.number);
System.out.println("Name: " + tObj2.name);
}
}
If you compile and run SerializationTest.java, you will get
the following output:
Number: 10
Name: NoStatic
The static field ‘name’ is assigned with the value “NoStatic”
when we created an object tObj3. number field is being deserialized and stored
back its value 10 but whereas name field value is taken from the class as it’s not
being serialized as it’s a static field.
What happens If a
variable is defined as static and transient both?
If a variable is defined as static and transient both then
static modifier will govern the behavior of variable and not transient. Transient
will be ignored if it’s accompanied with the static.
What happens If a
variable is defined as final and transient both?
Suppose if we have number
field of TestObject class with both final and transient modifiers as shown
below:
TestObject.java
package Serialization;
import
java.io.Serializable;
public class TestObject implements Serializable {
final transient int number;
String
name;
TestObject(int i, String s) {
number = i;
name = s;
}
}
If you compile and run SerializationTest.java, you will get
the following output:
Number: 0
Name: TestSerialization
Since number variable
is transient, it is not serialized and therefore, when the object is
deserialized, it is initialized to its default value 0. Since the variable number is final, when we try to manually
set the value to the variable number then
we get the compile time exception by saying “The final field TestObject.number cannot
be assigned”.
To get rid of this situation, we need to initialize the
final variable number with a constant expression. A constant expression is an
expression, which can be resolved at compile time, just like the ones we use in
the case labels of switch statement. Then the final field number gets its value 100 during
deserialization though its transient.
When we have the variable number initialized in the class TestObject as shown below:
TestObject.java
package Serialization;
import
java.io.Serializable;
public class TestObject implements Serializable {
final transient int number = 100;
String
name;
TestObject(int i, String s) {
// number
= i;
name = s;
}
}
If you compile and run SerializationTest.java, you will get
the following output:
Number: 100
Name: TestSerialization
No comments:
Post a Comment