The Transient Keyword in Java and Its Use
I recently came a cross in a study project of one of my friends that are studding the basics of programming in Java some forgotten sensitive information printed in text files and remembered the transient keyword in Java.
The transient keyword in Java plays an important role in terms of security and can be very useful in “accidents” like the one above as it will prevent the transmission of sensitive information like for example passwords to files, JSON messages etc that will require serialization.
To cut the long story short, if you define any variable as transient, it will not be serialized unless you define it as static or final.
Lets see some examples bellow.
In the following example we are going to define some variables transient, we are going to serialize them by writing them to a file, read them and see the impact.
import java.io.*;
public class TestTransient implements Serializable
{
// Normal variables
String a = "JCG";
String b = "IS";
// Transient variables
transient String c = "GREAT";
public static void main(String[] args) throws Exception
{
TestTransient foo = new TestTransient();
System.out.println("a before = " + foo.a);
System.out.println("b before = " + foo.b);
System.out.println("c before = " + foo.c);
System.out.println("---------------------");
// serialization
FileOutputStream fileOutputStream = new FileOutputStream("abc.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(foo);
// de-serialization
FileInputStream fileInputStream = new FileInputStream("abc.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
TestTransient output = (TestTransient) objectInputStream.readObject();
System.out.println("a from file = " + output.a);
System.out.println("b from file = " + output.b);
System.out.println("c from file = " + output.c);
}
}
The output is:
a before = JCG b before = IS c before = GREAT ----------------------- a from file = JCG b from file = IS c from file = null
As we can see, variable c that was marked as transient lost its value after the serialization.
Lets see another example.
import java.io.*;
public class TestTransient implements Serializable
{
// Normal variables
String a = "JCG";
String b = "IS";
// Transient variables
transient static String c = "GREAT";
transient final String d = "AGAIN!";
public static void main(String[] args) throws Exception
{
TestTransient foo = new TestTransient();
System.out.println("a before = " + foo.a);
System.out.println("b before = " + foo.b);
System.out.println("c before = " + foo.c);
System.out.println("d before = " + foo.d);
System.out.println("---------------------");
// serialization
FileOutputStream fileOutputStream = new FileOutputStream("abc.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(foo);
// de-serialization
FileInputStream fileInputStream = new FileInputStream("abc.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
TestTransient output = (TestTransient) objectInputStream.readObject();
System.out.println("a from file = " + output.a);
System.out.println("b from file = " + output.b);
System.out.println("c from file = " + output.c);
System.out.println("d from file = " + output.d);
}
}
The output is:
a before = JCG b before = IS c before = GREAT d before = AGAIN! ------------------------ a from file = JCG b from file = IS c from file = GREAT d from file = AGAIN!
So what happened here? Why were both c and d variables printed? The answer is because both of them were marked as either static or final.
- static variables are not part of the state of the object so the transient keyword cannot apply.
- final variables are already serialized by their values so again transient cannot apply.
So remember this keyword next time you have information you need to loose intentionally when serializing.
Had no idea that transient variables marked as static or final actually CAN be serialized. Good point!
Although kind of tricky, with static stuff serialized and accessed by multiple instances perhaps, could have unexpected results.
Good job Alexius.
Thanks!
Nice article thanks for it!