Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different between transient final of primitive type and transient final wrapper type

Tags:

java

What is different between transient final int and transient final Integer.

Using int:

transient final int a = 10;

Before Serialization:

a = 10

After serialization:

a = 10

Using Integer:

transient final Integer a = 10;

Before Serialization:

a = 10

After serialization:

a = null

full code:

public class App implements Serializable {
    transient final Integer transientFinal = 10;

    public static void main(String[] args) {
    try {
        ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream(
                "logInfo.out"));
        App a = new App();
        System.out.println("Before Serialization ...");
        System.out.println("transientFinalString = " + a.transientFinal);
        o.writeObject(a);
        o.close();
    } catch (Exception e) {
        // deal with exception
        e.printStackTrace();
    }

    try {

        ObjectInputStream in = new ObjectInputStream(new FileInputStream(
                "logInfo.out"));
        App x = (App) in.readObject();
        System.out.println("After Serialization ...");
        System.out.println("transientFinalString = " + x.transientFinal);
    } catch (Exception e) {
        // deal with exception
                    e.printStackTrace();
    }
}

}

like image 343
sharon Avatar asked Aug 14 '14 09:08

sharon


People also ask

Can we use transient with final?

However there is no compilation error. transient and final : final variables are directly serialized by their values, so there is no use/impact of declaring final variable as transient.

What is transient and serializable in Java?

The transient keyword in Java is used to avoid serialization. If any object of a data structure is defined as a transient , then it will not be serialized. Serialization is the ​process of converting an object into a byte stream.

Which of the following is not a primitive type?

Primitive data types - includes byte , short , int , long , float , double , boolean and char. Non-primitive data types - such as String , Arrays and Classes (you will learn more about these in a later chapter)

Are strings primitive data types?

The string data type is a non-primitive data type but it is predefined in java, some people also call it a special ninth primitive data type. This solves the case where a char cannot store multiple characters, a string data type is used to store the sequence of characters.


2 Answers

As mentioned in article

http://www.xyzws.com/Javafaq/can-transient-variables-be-declared-as-final-or-static/0

making field transient will prevent its serialization with one exception:

There is just one exception to this rule, and it is when the transient final field member is initialized to a constant expression as those defined in the JLS 15.28. Hence, field members declared this way would hold their constant value expression even after deserializing the object.

If you will visit mentioned JSL you will know that

A constant expression is an expression denoting a value of primitive type or a String

But Integer is not primitive type, and it is not String so it is not considered as candidate of constant expression so its value will not stay after serialization.

Demo:

class SomeClass implements Serializable {
    public transient final int a = 10;
    public transient final Integer b = 10;
    public transient final String c = "foo";

    public static void main(String[] args) throws Exception {

        SomeClass sc = new SomeClass();
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(sc);

        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(
                bos.toByteArray()));
        SomeClass sc2 = (SomeClass) ois.readObject();

        System.out.println(sc2.a);
        System.out.println(sc2.b);
        System.out.println(sc2.c);
    }
}

Output:

10
null
foo
like image 143
Pshemo Avatar answered Sep 20 '22 16:09

Pshemo


Only constant expressions will be assigned to the fields after deserialization. And the Integer cannot be expressed as constant expression, only primitive types and Strings can be according to http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28.

And the reason the final int is keeping its value is specified in http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5.3:

Even then, there are a number of complications. If a final field is initialized 
to a compile-time constant expression (§15.28) in the field declaration, changes 
to the final field may not be observed, since uses of that final field are 
replaced at compile time with the value of the constant expression.

Thus usages of this field are replaced with constants in compilation time and cannot be influenced by serialization in runtime.

like image 25
Gedrox Avatar answered Sep 21 '22 16:09

Gedrox