序列化Java中的最终瞬态如何工作

3 java serialization final transient java-8

我正在阅读有关transient和final关键字的内容,我找到了一个答案,我们不能使用带有final关键字的transient关键字.我试过并感到困惑,因为这里工作正常.

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){/**/}
    }
}
Run Code Online (Sandbox Code Playgroud)

这是Serializable Student类代码:

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);
        }
    }
Run Code Online (Sandbox Code Playgroud)

带有transient关键字的代码输出.

ABC04
DEF04
Run Code Online (Sandbox Code Playgroud)

输出没有临时关键字.

ABC34
DEF64
Run Code Online (Sandbox Code Playgroud)

你能解释为什么它工作正常吗?有没有错误?

最后什么应该是具有final关键字的瞬态行为?

ale*_*xbt 6

你的问题有点与此重复:

必须通过直接赋值初始值或在构造函数中初始化final字段.在反序列化期间,这些都不会被调用,因此必须在反序列化期间调用的"readObject()"私有方法中设置瞬态的初始值.为了实现这一目标,瞬态必须是非最终的.

声明为transient的任何字段都不是序列化的.此外,根据此博客文章,字段值甚至不会初始化为默认构造函数设置的值.当瞬态场是最终的时,这会产生挑战.

至于你的测试结果:

带有transient关键字的代码输出.ABC04 DEF04
无瞬态关键字输出.ABC34 DEF64

短暂的

显然,transient字段(第4个字符)未被序列化/反序列化(ABC 3 4-> ABC 0 4和DEF 6 4-> DEF 0 4)

静态的

static字段(第5个字符)也没有被反序列化!这只是因为您在同一个内存空间中执行操作,静态字段保留在所有实例中.因此,当您在student上设置静态字段,然后反序列化另一个学生时,静态字段当然仍具有相同的值!

这也解释了为什么在你的测试中你首先将静态字段设置为2然后4,但只4打印.在这种情况下,与序列化无关,只是静态字段行为.