【问题标题】:Use transient keyword in not Serializable class在不可序列化的类中使用瞬态关键字
【发布时间】:2013-08-04 19:15:03
【问题描述】:

在没有实现Serializable 的类中使用transient 关键字是否有意义?

因为没有实现Serializable 的类仍然可以被ObjectOutputStream 序列化。

【问题讨论】:

    标签: java serializable transient


    【解决方案1】:

    出于多种原因,您可能仍希望将其标记为瞬态。立即想到的两个是:

    • 它可以帮助传达该字段的语义目的。即,它可以帮助任何阅读您的代码的人理解该变量的含义

    • 第三方库可以使用关键字。例如,Google 的 Gson 库可以将任何对象序列化/反序列化到 JSON,无论它是否实现 Serializable。在这种情况下,Gson 将(默认情况下)跳过标记为瞬态的字段。

    【讨论】:

      【解决方案2】:

      因为对象序列化比 Serializable 的简单实现更复杂(想想代理:代理对象可以实现 Serializable,但不是原始对象,并且在您的代码中您仍然使用原始类)
      实现序列化的另一种方法是 Externalizable完全控制对象序列化的接口或(来自 javadoc):
      在序列化过程中需要特殊处理的类和 反序列化过程必须实现具有这些确切签名的特殊方法:

      private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException;
      private void writeObject(java.io.ObjectOutputStream stream) throws IOException
      private void readObjectNoData() throws ObjectStreamException;
      

      查看ObjectOutputStream javadoc 了解有关序列化过程/机制的更多信息。

      编辑:回答您的问题,transient 是一个仅在序列化上下文中使用的关键字,因此带有瞬态字段的 not Serializable 对象没有意义

      【讨论】:

        【解决方案3】:

        因为没有实现Serializable 的类仍然可以被ObjectOutputStream 序列化。

        这是不正确的。那会抛出一个NotSerializableException


        writeObject() 采用Object 而不是Serializable 的原因是签名来自实现接口ObjectOutput,该接口独立于序列化定义。但是,它会阻止 ObjectOutputStream 更改其签名。

        public interface ObjectOutput {
          // ...
          void writeObject(Object obj);
        }
        

        【讨论】:

        • 所以没有意义?
        • 这是一个有趣的评论,但它没有回答 OP 的问题。
        【解决方案4】:

        通常,如果超类实现Serializable,它的子类也是可序列化的。这是唯一可以使字段瞬态并且类不直接实现可序列化的情况,但除此之外,如果类不可序列化让它们瞬态是没有意义的。

        【讨论】:

        • 在这种情况下,该类还通过继承实现 Serializable。
        【解决方案5】:

        不,这没有意义。

        class State {
            // The 'transient' modifier has no effect here because
            // the 'State' class does not implement 'Serializable'.
            private transient int[] stateData;
        }
        

        【讨论】:

          猜你喜欢
          • 2012-07-05
          • 1970-01-01
          • 2015-08-11
          • 1970-01-01
          • 2020-02-25
          • 1970-01-01
          • 2018-09-12
          • 2016-07-01
          • 1970-01-01
          相关资源
          最近更新 更多