java - transient 如何在序列化 Java 中与 final 一起工作

标签 java serialization java-8 final transient

我正在阅读有关 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/

相关文章:

java - 如何在vertx中使用apache kafka,无论是在服务器端还是客户端?

java - Kubernetes 服务节点端口不工作

java - 解释整数溢出的两种方法

serialization - Linq to Xml VS XmlSerializer VS DataContractSerializer

java - 对象序列化查询和类路径

java - 编译时间 : no instance(s) of type variable(s) U exist

java - 用Java编写的开源规则引擎

java - 使用返回不正确 boolean 值的 boolean 值数组列表反序列化对象

java - 抽象类泛型通过构造函数继承

java - 是否可以在 Java 7 源代码级别使用 ConcurrentHashmap 计算?