java - 最终 transient 字段和序列化

标签 java serialization final

在 Java 中序列化后是否可以将 final transient 字段设置为任何非默认值?我的用例是一个缓存变量——这就是它是 transient 的原因。我还有一个习惯,就是制作不会改变的 Map 字段(即 map 的内容改变了,但对象本身保持不变)final。然而,这些属性似乎是矛盾的——虽然编译器允许这样的组合,但在反序列化之后,我不能将该字段设置为 null 之外的任何内容。

我尝试了以下方法,但没有成功:

  • 简单的字段初始化(如示例所示):这是我通常所做的,但在反序列化后似乎没有进行初始化;
  • 在构造函数中初始化(我相信这在语义上与上面相同);
  • readObject() 中分配字段 - 由于该字段是 final,因此无法完成。

在示例中 cachepublic 仅用于测试。

import java.io.*;
import java.util.*;

public class test
{
    public static void main (String[] args) throws Exception
    {
        X  x = new X ();
        System.out.println (x + " " + x.cache);

        ByteArrayOutputStream  buffer = new ByteArrayOutputStream ();
        new ObjectOutputStream (buffer).writeObject (x);
        x = (X) new ObjectInputStream (new ByteArrayInputStream (buffer.toByteArray ())).readObject ();
        System.out.println (x + " " + x.cache);
    }

    public static class X implements Serializable
    {
        public final transient Map <Object, Object>  cache = new HashMap <Object, Object> ();
    }
}

输出:

test$X@1a46e30 {}
test$X@190d11 null

最佳答案

不幸的是,简短的回答是“不”——我经常想要这个。但 transient 不能是最终的。

必须通过直接分配初始值或在构造函数中初始化最终字段。在反序列化期间,这些都不会被调用,因此必须在反序列化期间调用的“readObject()”私有(private)方法中设置 transient 的初始值。而要让它发挥作用, transient 必须是非最终的。

(严格来说,final 只是在第一次被读取时才是 final,所以有可能会在读取之前分配一个值,但对我来说,这走得太远了。)

关于java - 最终 transient 字段和序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2968876/

相关文章:

java - 在 CentOS 6 中设置 JAVA_HOME 和 CLASSPATH

java - Java中对象的初始化

java - GWT 与 Solr 索引的接口(interface)

java - JSP 表单标签操作属性 URI Spring MVC

java - 我不知道如何修复此代码?

oop - 用于将对象解析为特定模型的设计模式,反之亦然

javascript - 如何序列化 JavaScript 中的函数?

java - 如何序列化第三方不可序列化的最终类(例如谷歌的 LatLng 类)?

java - 如何使用父类(super class)中存在的名称重命名方法?

java - java中的最终字段继承