The difference between a temporary ending of a primitive type and a passing ending wrapper type

What is the difference 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(); } } 

}

+6
source share
2 answers

As mentioned in the article

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

creating a field transient will prevent its serialization with one exception:

There is only one exception to this rule, and this is when a member of the final field of the transient is initialized as a constant expression like those defined in JLS 15.28 . Therefore, field members declared in this way retain their expression of constant value even after deserializing the object.

If you visit the mentioned JSL, you will find out that

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

But Integer not a primitive type, and it is not a String, so it is not considered a constant expression candidate, so its value will not remain 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 
+6
source

After deserialization, only constant expressions will be assigned. And Integer cannot be expressed as a constant expression, only primitive types and strings can match http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28 .

And the reason final int retains its value is listed 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, the use of this field is replaced by constants at compile time and cannot depend on serialization at run time.

+2
source

Source: https://habr.com/ru/post/973807/


All Articles