java - 用作锁的 transient 最终字段为空

标签 java serialization nullpointerexception final transient

以下代码抛出一个NullPointerException

import java.io.*;

public class NullFinalTest {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        Foo foo = new Foo();
        foo.useLock();
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        new ObjectOutputStream(buffer).writeObject(foo);
        foo = (Foo) new ObjectInputStream(new ByteArrayInputStream(buffer.toByteArray())).readObject();
        foo.useLock();
    }

    public static class Foo implements Serializable {
        private final String lockUsed = "lock used";
        private transient final Object lock = new Object();
        public void useLock() {
            System.out.println("About to synchronize");
            synchronized (lock) { // <- NullPointerException here on 2nd call
                System.out.println(lockUsed);
            }
        }
    }
}

这是输出:

About to synchronize
lock used
About to synchronize
Exception in thread "main" java.lang.NullPointerException
    at NullFinalTest$Foo.useLock(NullFinalTest.java:18)
    at NullFinalTest.main(NullFinalTest.java:10)

lock 怎么可能为空?

最佳答案

用作锁的 transient 最终字段为空

以下是关于 transient 变量的一些事实:

- Transient 关键字在实例变量上使用时,将阻止该实例变量被序列化。

- 在反序列化时, transient 变量获得它们的默认值......

例如:

  • 对象引用变量为 null
  • int 到 0
  • boolean 值到false,等......

这就是反序列化时出现 NullPointerException 的原因...

关于java - 用作锁的 transient 最终字段为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12324472/

相关文章:

c# - 序列化 GradientBrush

java - NullPointerException java,即使正在显示值?

java - JMS 连接和 session 池

java - 从保持 Activity 状态的 JButton 进程中关闭 JFrame

java - 如何序列化类型 X 的列表,填充类型 Y 的对象,该对象扩展 X,并且在反序列化时仍然获得 Y 元素?

java - 使用 JPQL 命名查询调用方法时 .jsp 出现 NullPointerException

android - Gradle 同步时此 normalizeAndCheck(UnixPath.java) NullPointerException 的修复方法是什么?

java - 有没有办法以声明的顺序从java类中获取私有(private)字段名称

java - 我们的应用程序中可以同时拥有 RESTful 和 SOAP Web 服务吗

java - 将java对象转换为管道分隔字符串