如何序列化Java类的静态数据成员?

Mad*_*hik 32 java serialization static-members

当我们序列化对象时,静态成员不是序列化的,但是如果我们需要这样做,有什么办法吗?

Kat*_*one 18

第一个问题是为什么需要序列化静态成员?

静态成员与类关联,而不是与实例关联,因此在序列化实例时包含它们没有意义.

第一个解决方案是使这些成员不是静态的.或者,如果这些成员在原始类和目标类(相同的类,但可能是不同的运行时环境)中相同,则根本不要对它们进行序列化.

我对如何发送静态成员有一些想法,但我首先需要查看用例,因为在所有情况下都意味着更新目标类,我没有找到一个很好的理由这样做.

  • 你需要直接存储这个号码吗?如果在反序列化每个Car时更新数字(通过覆盖readObject),它将正确反映序列化中的汽车数量. (4认同)
  • 假设我想计算像Car这样的类的实例数.并且我没有使用数据库.所以在这种情况下,在应用程序关闭后,我需要将此信息与其他信息一起存储. (2认同)

Vla*_*hev 16

人们,静态并不意味着IMMUTABLE.例如,我可能想要在JVM和/或主机重新启动之后序列化计算的整个状态(是的,包括静态字段 - 计数器等)以便稍后恢复.

正如已经说过的那样,正确的答案是使用Externalizable,而不是Serializable接口.然后,您可以完全控制外部化的内容和方式.

  • 可变静电通常意味着破碎. (3认同)
  • 是.让它成为一个单身人士.序列化单例.或者,更好的是,摆脱共享静态存储,将其存储在显式上下文对象中. (3认同)
  • 再想想。例如,多线程遗传算法怎么样?共享(静态)存储用于保存评估变体的注册表。让它成为单例?可能,但它有自己的缺点。 (2认同)
  • ...然后另一群纯粹主义者会抱怨单例模式是反模式我也应该摆脱它。至于“显式上下文对象”,不同的线程是如何访问的?通过静态方法?怎么样更好? (2认同)

Nic*_*olt 5

您可以通过实现以下内容来控制序列

private void writeObject(ObjectOutputStream out) throws IOException;

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException;
Run Code Online (Sandbox Code Playgroud)

有序列化的完整描述http://java.sun.com/developer/technicalArticles/Programming/serialization/.

正如其他答案所说,序列化静态并不是真的有意义,因为它不是你要序列化的对象,而是需要这样做,闻起来像你的代码还有其他问题给我.


小智 5

这是静态字段的序列化:newBookingNumber.

class Booking implements Serializable
{

    /**
     * Generated serial version ID.
     */

    private static final long serialVersionUID = 5316748056989930874L;

    // To hold new booking number.
    private static int newBookingNumber = 0;

    // The booking number.
    private int bookingNumber;


    /* 
     * Default serializable fields of a class are defined to be 
     * the non-transient and non-static fields. So, we have to 
     * write and read the static field separately.
     */
    private void writeObject(ObjectOutputStream oos)
        throws IOException 
    {
        oos.defaultWriteObject();
        oos.writeObject(new Integer(newBookingNumber));
    }

    private void readObject(ObjectInputStream ois)
    throws ClassNotFoundException, IOException 
    {
        ois.defaultReadObject();
        newBookingNumber = (Integer)ois.readObject();
    }
}
Run Code Online (Sandbox Code Playgroud)