简体   繁体   English

为什么静态瞬态场被序列化?

[英]why static transient field is serialized?

I´ve been reading that the static fields are not serialized but, after testing it, I saw that´s not true. 我一直在读静态字段没有序列化,但经过测试后,我发现这不是真的。

The static modifier even overrides the transient modifier and makes the field serializable. 静态修改器甚至会覆盖transient修改器并使该字段可序列化。

I write one example from a book that shows that a static transient field is serialized. 我从一本书中写了一个例子,该书显示静态瞬态场被序列化。

import java.io.*;

class USPresident implements Serializable {

    private static final long serialVersionUID = 1L;

    @Override
    public String toString() {
        return "US President [name=" + name
                + ", period=" + period + ", term=" + term + "]";
    }

    public USPresident(String name, String period, String term) {
        this.name = name;
        this.period = period;
        this.term = term;
    }
    private String name;
    private String period;
    private  static transient  String term;
}

class TransientSerialization {

    public static void main(String[] args) {
        USPresident usPresident = new USPresident("Barack Obama", "2009 to --", "56th term");
        System.out.println(usPresident);
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("USPresident.data"))) {
            oos.writeObject(usPresident);
        } catch (IOException ioe) {
// ignore
        }
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("USPresident.data"))) {
            Object obj = ois.readObject();
            if (obj != null && obj instanceof USPresident) {
                USPresident presidentOfUS = (USPresident) obj;
                System.out.println(presidentOfUS);

            }
        } catch (IOException ioe) {
// ignore
        } catch (ClassNotFoundException e) {
// ignore
        }
    }
}

Is wrong the general concept that static fields are not serialized? 静态字段未序列化的一般概念是错误的吗? Is it just a recommendation? 这只是推荐吗? Why the transient modifier doen't take effect with static ? 为什么瞬态修改器不会对静态生效?

note: I understand that initialize a static field in a constructor is an odd code, but the compiler let me do it and it's just in order to understand static fields serialization. 注意:我知道在构造函数中初始化静态字段是一个奇怪的代码,但编译器允许我这样做,这只是为了理解静态字段序列化。

This has nothing to do with serialization but due to the fact that you are setting the static field when you create your usPresident variable. 这与序列化无关,但是由于您在创建usPresident变量时设置静态字段。 This sets the field for the class of that JVM. 这将为该JVM的设置字段。 Try reading in the serialized president in a different program and see that the transient field is not serialized. 尝试在不同的程序中读取序列化的总统,并看到瞬态字段未序列化。

As an aside: consider not ignoring your exceptions. 暂且不说:考虑不要忽视你的例外情况。


For example, refactored, your code could look like this: 例如,重构后,您的代码可能如下所示:

class USPresident implements Serializable {

   private static final long serialVersionUID = 1L;

   @Override
   public String toString() {
      return "US President [name=" + name + ", period=" + period + ", term="
            + term + "]";
   }

   public USPresident(String name, String period, String term) {
      this.name = name;
      this.period = period;
      this.term = term;
   }

   private String name;
   private String period;
   private static transient String term;
}

class TransientSerialization {

   public static void main(String[] args) {
      serializePresident();
      deserializePresident();
   }

   private static void deserializePresident() {
      ObjectInputStream ois = null;
      try {
         ois = new ObjectInputStream(new FileInputStream(
               "USPresident.data"));
         Object obj = ois.readObject();
         if (obj != null && obj instanceof USPresident) {
            USPresident presidentOfUS = (USPresident) obj;
            System.out.println(presidentOfUS);

         }
      } catch (IOException ioe) {
         ioe.printStackTrace();
      } catch (ClassNotFoundException e) {
         e.printStackTrace();
      } finally {
         if (ois != null) {
            try {
               ois.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }
      }
   }

   private static void serializePresident() {
      USPresident usPresident = new USPresident("Barack Obama", "2009 to --",
            "56th term");
      System.out.println(usPresident);
      ObjectOutputStream oos = null;
      try {
         oos = new ObjectOutputStream(new FileOutputStream("USPresident.data"));
         oos.writeObject(usPresident);
         oos.close();
      } catch (IOException ioe) {
         ioe.printStackTrace();
      } finally {
         if (oos != null) {
            try {
               oos.close();
            } catch (IOException e) {
               e.printStackTrace();
            }
         }
      }
   }
}

The second time your run it, change the main method to: 第二次运行它,将main方法更改为:

   public static void main(String[] args) {
      // serializePresident();
      deserializePresident();
   }

And see what comes up. 看看会出现什么。

For me, the first run returns: 对我来说,第一次运行返回:

US President [name=Barack Obama, period=2009 to --, term=56th term]
US President [name=Barack Obama, period=2009 to --, term=56th term]

and the second run returns: 并且第二次运行返回:

US President [name=Barack Obama, period=2009 to --, term=null]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM