Java 序列化中瞬态如何与 Final 配合使用

2023-12-27

我正在阅读有关瞬态和最终关键字的内容,我发现答案是我们不能将瞬态关键字与最终关键字一起使用。我尝试过但很困惑,因为在这里它工作正常。

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(使用前将#替换为@)

Java 序列化中瞬态如何与 Final 配合使用 的相关文章

随机推荐