Java 原语类型的瞬态final和瞬态final包装器类型之间的差异
Java 原语类型的瞬态final和瞬态final包装器类型之间的差异,java,Java,transient final int和transient final Integer之间有什么不同 使用int: transient final int a = 10; 序列化之前: a = 10 a = 10 a = 10 a = null 序列化后: a = 10 a = 10 a = 10 a = null 使用整数: transient final Integer a = 10; 序列化之前: a = 10 a = 10 a = 10 a = null 序列
transient final int
和transient final Integer
之间有什么不同
使用int
:
transient final int a = 10;
序列化之前:
a = 10
a = 10
a = 10
a = null
序列化后:
a = 10
a = 10
a = 10
a = null
使用整数
:
transient final Integer a = 10;
序列化之前:
a = 10
a = 10
a = 10
a = null
序列化后:
a = 10
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();
}
}
}反序列化后,只有常量表达式才会分配给字段。整数不能表示为常量表达式,只能根据基元类型和字符串
final int
保持其值的原因如下所示:
因此,该字段的用法在编译时被常量替换,并且不受运行时序列化的影响。如本文所述 使字段为瞬态将阻止其序列化,但有一个例外: 此规则只有一个例外,即瞬态最终字段成员初始化为中定义的
常量表达式时。因此,即使在反序列化对象之后,以这种方式声明的字段成员也将保持其常量值表达式
如果您访问提到的JSL,您将知道
常量表达式是表示基元类型
的值或字符串
但是,Integer
不是基元类型,也不是字符串,所以它不被视为常量表达式的候选,所以它的值在序列化后不会保留
演示:
输出:
10
null
foo
你在哪里工作?我在你的代码中看不到任何内容。在transient
和final
中标记某些内容的预期目的是什么?这可能会有所帮助-。嗨@Gedrox,我在发布此问题之前刚刚阅读了这篇文章。在这篇文章中,一切都很好,但我尝试使用整数而不是字符串,它不起作用。我可以猜到,由于自动装箱,Integer transientFinal=10
没有被视为常量表达式。请参阅–“编译时常量表达式的定义只能应用于原语和字符串”。我想知道为什么序列化会涉及瞬态字段。反序列化后,我至少希望a==0
。在Oracle文档中找不到任何指定此项的引用。我猜这种行为的定义比序列化层更深。我猜带有常量表达式的字段甚至在构建对象之前就已经初始化了,可能存储在类定义中。