我正在阅读有关瞬态和最终关键字的内容,我发现答案是我们不能将瞬态关键字与最终关键字一起使用。我尝试过但很困惑,因为在这里它工作正常。
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);
}
}
带有瞬态关键字的代码输出。
ABC04
DEF04
不带瞬态关键字的输出。
ABC34
DEF64
你能解释一下为什么它工作正常吗?有错误吗?
最后,带有final关键字的transient的行为应该是什么?
你的问题有点重复:
- 最终瞬态字段和序列化 https://stackoverflow.com/questions/2968876/final-transient-fields-and-serialization
- 用作锁的瞬态最终字段为空 https://stackoverflow.com/questions/12324472/a-transient-final-field-used-as-a-lock-is-null
Final 字段必须通过直接分配初始值或在构造函数中进行初始化。在反序列化期间,这两个都不会被调用,因此瞬态的初始值必须在反序列化期间调用的“readObject()”私有方法中设置。为了使其发挥作用,瞬态必须是非最终的。
and
任何声明为瞬态的字段都不会被序列化。此外,根据这篇博客文章,字段值甚至没有初始化为默认构造函数设置的值。当瞬态场是最终的时,这会带来挑战。
至于你的测试结果:
带有瞬态关键字的代码输出。
ABC04 DEF04
不带瞬态关键字的输出。
ABC34 DEF64
短暂的
显然,transient
字段(第四个字符)没有被序列化/反序列化(ABC34->ABC04、DEF64->防御04)
static
The static
字段(第 5 个字符)也没有被反序列化!这只是因为您在同一内存空间中执行操作,并且静态字段在所有实例中保留。因此,当您在学生上设置静态字段,然后反序列化另一个学生时,静态字段当然仍然具有相同的值!
这也解释了为什么在您的测试中您首先将静态字段设置为2
和
然后4
, 但只有4
被打印。在这种情况下与序列化无关,只是静态字段行为。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)