用作锁的瞬态最终字段为空

Rea*_*ted 6 java serialization final nullpointerexception 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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是输出:

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

怎么lock可能是null?

Kum*_*tra 14

A transient final field used as a lock is null

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

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

-在反序列化时,瞬态变量达到其默认值 .....

例如:

  • 对象引用变量 null
  • int到 0
  • 布尔false,等等.......

这就是你NullPointerException在反序列化时得到的原因......