transient final int
和transient final Integer
之间有何不同。
使用int
:
transient final int a = 10;
序列化之前:
a = 10
序列化后:
a = 10
使用Integer
:
transient final Integer a = 10;
序列化之前:
a = 10
序列化后:
a = null
完整代码:
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();
}
}
}
答案 0 :(得分:6)
如文章
所述http://www.xyzws.com/Javafaq/can-transient-variables-be-declared-as-final-or-static/0
使字段瞬态将阻止其序列化,但有一个例外:
此规则只有一个例外,即瞬态最终字段成员初始化为
constant expression
时primitive type
中定义的成员。因此,即使在反序列化对象之后,以这种方式声明的字段成员也将保持其常量值表达式。
如果您将访问提到的JSL,您将知道
常量表达式是表示值
的表达式String
或Integer
但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);
}
}
不是原始类型,它不是String,因此它不被视为常量表达式的候选者,因此它的值在序列化后不会保留。
演示:
10
null
foo
输出:
{{1}}
答案 1 :(得分:2)
反序列化后,只有常量表达式将分配给字段。并且Integer
不能表示为常量表达式,只有原始类型和字符串可以符合http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28。
在http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5.3中指定了final int
保持其值的原因:
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.
因此,该字段的用法在编译时会被常量替换,并且不会受到运行时序列化的影响。