How to Serialize Static Data Members of a Java Class

How to serialize static data members of a Java class?

The first question is why you need to serialize the static members?

Static members are associated with the class, not the instances, so it does not make sense to include them when serializing an instance.

The first solution is to make those members not static. Or, if those members are the same in the original class and the target class (same class, but possibly different runtime environments), don't serialize them at all.

I have a few thoughts on how one could send across static members, but I first need to see the use case, as in all cases that means updating the target class, and I haven't found a good reason to do so.

Java static serialization rules?

statics are implicitly transient, so you don't need to declare them as such.

Serialization is for serializing instances, not classes. static fields (methods are irrelevant since they are part of the class definition so they aren't serialized) will be reinitialized to whatever value they are set to when the class is loaded.

If you have a mutable static field, then the changes made to that value will be lost.

Serialize static attributes in Java

From this article:

Tip 1: Handling Static Variables

Java classes often hold some
globally relevant value in a static
class variable. We won't enter into
the long history of the debate over
the propriety of global variables -
let's just say that programmers
continue to find them useful and the
alternatives suggested by purists
aren't always practical.

For static variables that are
initialized when declared,
serialization doesn't present any
special problems. The first time the
class is used, the variable in
question will be set to the correct
value.

Some statics can't be initialized this
way. They may, for instance, be set by
a human during the running time of the
program. Let's say we have a static
variable that turns on debugging
output in a class. This variable can
be set on a server by sending it some
message, perhaps from a monitor
program. We'll also imagine that when
the server gets this message, the
operator wants debugging turned on in
all subsequent uses of the class in
the clients that are connected to that
server.

The programmer is now faced with a
difficulty. When the class in question
arrives at the client, the static
variable's value doesn't come with it.
However, it contains the default
static state that's set when the
class's no-argument constructor is
called by writeObject(). How can the
client programs receive the new
correct value?

The programmer could create another
message type and transmit that to the
client; however, this requires a
proliferation of message types,
marring the simplicity that the use of
serialization can achieve in
messaging. The solution we've come up
with is for the class that needs the
static transmitted to include a
"static transporter" inner class. This
class knows about all the static
variables in its outer class that must
be set. It contains a member variable
for each static variable that must be
serialized. StaticTransporter copies
the statics into its member variables
in the writeObject() method of the
class. The readObject() method
"unwraps" this bundle and transmits
the server's settings for the static
variables to the client. Since it's an
inner class, it'll be able to write to
the outer class's static variables,
regardless of the level of privacy
with which they were declared.

And from another article:

Static or transient data


However, this "ease" is not true in
all cases. As we shall see,
serialization is not so easily applied
to classes with static or transient
data members. Only data associated
with a specific instance of a class is
serialized, therefore static data,
that is, data associated with a class
as opposed to an instance, is not
serialized automatically. To serialize
data stored in a static variable one
must provide class-specific
serialization.

Similarly, some classes may define
data members to use as scratch
variables. Serializing these data
members may be unnecessary. Some
examples of transient data include
runtime statistics or hash table
mapping references. These data should
be marked with the transient modifier
to avoid serialization. Transient, by
definition, is used to designate data
members that the programmer does not
want or need to be serialized. See
Java in a Nutshell, page 174: mouse
position, preferred size, file handles
(machine specific (native code)).

When writing code if something is
declared transient, then this triggers
(to programmer) necessity of the
posibility of special code for
serialization later.

To serialize an object, you create
some sort of OutputStream object and
then wrap it inside an
ObjectOutputStream object. At this
point you only need to call
writeObject() and your object is
magically serialized and sent to the
OutputStream. To reverse the process,
you wrap an InputStream inside an
ObjectInputStream and call
readObject(). What comes back is, as
usual, a handle to an upcast Object,
so you must downcast to set things
straight. If you need to dynamically
query the type of the object, you can
use the getClass method. Specifically
dk.getClass.getName() returns the name
of the class that dk is an instance
of. I.e., this asks the object for the
name of its corresponding class
object. (Hmmm, True, but what about
syntax? I still need to know what it
is to declare it...too bad) (C++ can
do this in one operation (dynamic_cast
(gives null if wrong type)), java can
use instanceof operator to check if it
is what I think (see Core Java, Ch5
Inheritence, Casting section)

java static variable serialization

The static field value was not serialized. The output is printing the new value of the static field simply because you modified it to 999999 but you never reset its value to the old one before de-serizalizing. Since the field is static, the new value is reflected in any instance of ChildClass.

To properly assert that the field is not serialized, reset the value to 10001 before de-serializing the object, and you will notice that its value is not 999999.

...
ChildClass.setStaticState(10001);

FileInputStream fi = null;
ObjectInputStream ois = null;
ChildClass streamed;

...
// when de-serializing, the below will print "state101 static state 10001"
System.out.println(streamed.toString());

Why Static Fields are not Serialized

As class level values they are "global" to the all instances of that class.

So what would be the "correct" value when deserializing several instances of such class? There can only be one instance of such values. So static fields are linked to the class and are serialized and deserialized with the class itself not with the different instances.

Are static variables serialized in Serialization process

serialVersionUID is a special static variable used by the serialization and deserialization process, to verify that a local class is compatible with the class used to serialize an object. It's not just a static variable as others, which are definitely not serialized.

When an object of a class is first serialized, a class descriptor containing among other things the class name and serial version UID is written to the stream. When this is deserialized, the JVM checks if the serial version UID read from the stream is the same as the one of the local class. If they're not, it doesn't even try to deserialize the object, because it knows the classes are incompatible.

force serialization of static fields

You could write a method to use reflection to serialize all static methods. A static method can be marked transient which would normally be redundant, but you could use this to highlight static fields you don't want to serialize. You can call this method from your writeObject() to save you having to do this for every field.

Java serialization: static variables not serializable: workaround

A better solution (IMO) would be to make lastIdUsed an instance field of the PhoneBook class. It sounds like you are already serializing an instance of that class ...

FWIW - making lastIdUsed an instance field of Person is just bad object modelling. The field is almost never going to be useful and almost never going to have a valid value. It will only have a valid value in the case of the first serialized Person in a PhoneBook.



Related Topics



Leave a reply



Submit