我正在阅读有关 transient 和 final 关键字的文章,我找到了我们不能将 transient 关键字与 final 关键字一起使用的答案。我尝试过并感到困惑,因为它在这里工作正常。
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
import java.io.Serializable;
public class SerExample{
public static void main(String... args){
Student foo = new Student(3,2,"ABC");
Student koo = new Student(6,4,"DEF");
try
{
FileOutputStream fos = new FileOutputStream("abc.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(foo);
oos.writeObject(koo);
oos.close();
fos.close();
}
catch(Exception e){/**/}
try{
FileInputStream fis = new FileInputStream("abc.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
System.out.println(ois.readObject());
System.out.println(ois.readObject());
fis.close();
ois.close();
}catch(Exception e){/**/}
}
}
这是可序列化的学生类代码:
class Student implements Serializable{
private transient final int id;
private transient static int marks;
private String name;
public Student(int id, int marks, String name){
this.id = id;
this.marks = marks;
this.name = name;
}
public Student(){
id=0;
}
@Override
public String toString(){
return (this.name + this.id + this.marks);
}
}
带有 transient 关键字的代码输出。
ABC04
DEF04
没有 transient 关键字的输出。
ABC34
DEF64
您能解释一下为什么它运行良好吗?有错误吗?
最后,带有 final 关键字的 transient 行为应该是什么?
最佳答案
你的问题有点重复:
A final field must be initialized either by direct assignment of an initial value or in the constructor. During deserialization, neither of these are invoked, so initial values for transients must be set in the 'readObject()' private method that's invoked during deserialization. And for that to work, the transients must be non-final.
和
Any field that is declared transient is not serialized. Moreover, according to this blog post, field values are not even initialized to the values that would be set by a default constructor. This creates a challenge when a transient field is final.
至于你的测试结果:
Code output with transient keyword. ABC04 DEF04
Output without transient keyword. ABC34 DEF64
短暂的
显然,transient
字段(第 4 个字符)未被序列化/反序列化(ABC34->ABC04 和 DEF 64->防御04)
静态
static
字段(第 5 个字符)也没有被反序列化!这仅仅是因为您在同一内存空间中执行操作,并且静态字段保留在所有实例中。所以当你在学生身上设置静态字段,然后反序列化另一个学生时,当然静态字段仍然具有相同的值!
这也解释了为什么在您的测试中您首先将静态字段设置为 2
并且
然后 4
,但只打印 4
。在这种情况下与序列化无关,只是静态字段行为。
关于java - transient 如何在序列化 Java 中与 final 一起工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37614088/