小编典典

序列化Java中的静态属性

java

如果我尝试序列化静态属性会怎样?

谢谢


阅读 464

收藏
2020-11-30

共1个答案

小编典典

从这篇文章

提示1:处理静态变量

Java类通常在静态类变量中包含一些全局相关的值。我们不会进入有关全局变量是否适当的争论的悠久历史-
只能说程序员继续发现它们有用,而纯粹主义者建议的替代方案并不总是可行的。

对于声明时初始化的静态变量,序列化不会出现任何特殊问题。第一次使用该类时,相关变量将设置为正确的值。

某些静态无法通过这种方式初始化。例如,它们可以由人在程序运行时设置。假设我们有一个静态变量可以打开类中的调试输出。可以在服务器上通过发送一些消息(可能是从监视程序发送)来设置此变量。我们还将想象,当服务器收到此消息时,操作员希望在连接到该服务器的客户端中对该类的所有后续使用中打开调试。

程序员现在面临困难。当相关类到达客户端时,静态变量的值不随其提供。但是,它包含在调用类的无参数构造函数时设置的默认静态状态writeObject()。客户端程序如何接收新的正确值?

程序员可以创建另一种消息类型,并将其发送给客户端。但是,这需要增加消息类型,这损害了在消息传递中使用序列化可以实现的简单性。我们想出的解决方案是针对需要静态传输的类,以包括“静态传输器”内部类。此类知道其外部类中必须设置的所有静态变量。它包含每个必须序列化的静态变量的成员变量。StaticTransporter
writeObject()在类的方法中将静态变量复制到其成员变量中。的readObject()方法“解包”此捆绑包并将静态变量的服务器设置发送给客户端。由于它是一个内部类,因此可以声明外部类的静态变量,而不管其声明的隐私级别如何。

从另一篇文章

静态或瞬态数据

但是,这种“缓解”并非在所有情况下都是正确的。正如我们将看到的,将序列化应用于具有静态或瞬态数据成员的类并不容易。只有与某个类的特定实例相关联的数据才被序列化,因此静态数据(即与某个实例相关联的与类相关联的数据)不会被自动序列化。要序列化存储在静态变量中的数据,必须提供特定于类的序列化。

同样,某些类可能会定义用作临时变量的数据成员。序列化这些数据成员可能是不必要的。瞬态数据的一些示例包括运行时统计信息或哈希表映射引用。这些数据应标记有瞬态修饰符,以避免序列化。根据定义,瞬态用于指定程序员不希望或不需要序列化的数据成员。请参阅第74页的“简而言之Java”:鼠标位置,首选大小,文件句柄(特定于计算机(本机代码))。

当编写代码时,如果某些东西被声明为瞬态的,则(对于程序员而言)这触发了特殊代码可能在以后进行序列化的必要性。

要序列化对象,请创建某种OutputStream对象,然后将其包装在ObjectOutputStream对象中。这时,您只需要调用即可
writeObject(),您的对象已被神奇地序列化并发送到OutputStream。要逆转该过程,请将InputStream包装在ObjectInputStream中,然后调用
readObject(。像往常一样,返回的是向上转换对象的句柄,因此您必须向下转换以使事情变得正确。如果需要动态查询对象的类型,则可以使用getClass方法。具体
dk.getClass.getName()返回该类的名称dk是的实例。即,这向对象询问其对应的类对象的名称。(嗯,是的,但是语法呢?我仍然需要知道声明它的含义……太糟糕了)(C
++可以在一个操作中做到这一点(dynamic_cast
(如果类型错误,则为null)),java可以使用instanceof运算符来检查它是否是我的想法(请参阅Core
Java,Ch5继承,强制转换部分)

2020-11-30