为什么 java 中的 String 不覆盖 readObject?

why String in java does not override readObject?

我正在研究 effective java 并且在 immutability(Item 15) 中写道: 在构造函数、访问器和 readObject 方法(第 76 项)中制作防御性副本(第 39 项)。

并且在项目 76 中,建议覆盖 readObject 并通过妥协 final 关键字创建可变对象的防御副本。所以我检查了 java 中的字符串 class 并检查他们是否对 final char value[]; 做了同样的事情但是 readObject 没有被覆盖。

我对此感到困惑?请回答。

readObject 应在反序列化具有需要特殊处理的非瞬态字段的对象时使用。字符串是可序列化的,没有这样的字段,所以与它无关。

至于防御性副本,因为字符串是不可变的 - 您不必担心。

字符串、数组和枚举是序列化中的特例,不会像其他对象那样通过 readObject/writeObject 进行序列化。

这是来自 String.java 的评论:

   /**
    * Class String is special cased within the Serialization Stream Protocol.
    *
    * A String instance is written initially into an ObjectOutputStream in the
    * following format:
    * <pre>
    *      <code>TC_STRING</code> (utf String)
    * </pre>
    * The String is written by method <code>DataOutput.writeUTF</code>.
    * A new handle is generated to  refer to all future references to the
    * string instance within the stream.
    */

这里是 ObjectOutputStream.java 的特例:

// remaining cases
if (obj instanceof String) {
    writeString((String) obj, unshared);
} else if (cl.isArray()) {
    writeArray(obj, desc, unshared);
} else if (obj instanceof Enum) {
    writeEnum((Enum) obj, desc, unshared);
} else if (obj instanceof Serializable) {
    writeOrdinaryObject(obj, desc, unshared);
} else {
    if (extendedDebugInfo) {
        throw new NotSerializableException(
            cl.getName() + "\n" + debugInfoStack.toString());
    } else {
        throw new NotSerializableException(cl.getName());
    }
}