static final variable and serialization

S

swengineer001

I have a design that has a collection of serializable objects which
contain several static final variables. I am wondering what will
happen with these if I were to output the collection to a file. I am
just learning Java but have several years of embedded experience with
C. In C I would have had these variables #defined in a header and not
written them to the file.

Thanks for any insight
 
D

Daniel Pitts

I have a design that has a collection of serializable objects which
contain several static final variables. I am wondering what will
happen with these if I were to output the collection to a file. I am
just learning Java but have several years of embedded experience with
C. In C I would have had these variables #defined in a header and not
written them to the file.

Thanks for any insight

I believe serializing works on the instance level. You could (as
Andrew Thompson suggests) write a test a report your findings for
future programmers.
 
T

Tom Hawtin

I have a design that has a collection of serializable objects which
contain several static final variables. I am wondering what will
happen with these if I were to output the collection to a file. I am
just learning Java but have several years of embedded experience with
C. In C I would have had these variables #defined in a header and not
written them to the file.

Only instance data is serialised. If instances have references to the
objects pointed to be the static variables, those objects will be
serialised to. However, there is no record that static variables pointed
to those instances. If they were, what would you expect to happen to
those static final variables when you deserialised?

In general, avoid mutable static data like the plague (even if labeled
'singleton' to pretend that it isn't a bodge).

Tom Hawtin
 
T

Twisted

Only instance data is serialised. If instances have references to the
objects pointed to be the static variables, those objects will be
serialised to. However, there is no record that static variables pointed
to those instances. If they were, what would you expect to happen to
those static final variables when you deserialised?

In general, avoid mutable static data like the plague (even if labeled
'singleton' to pretend that it isn't a bodge).

Tom Hawtin

Of course, you could end up with this situation:
Static -> object
Instance -> object
before serialization,
Static -> object
Instance -> object copy
after.
Previously, the static variable reference == the instance's;
subsequently, they are no longer ==, though probably equals() if that
isn't the default object equals().

If that matters, you have a problem. The solution is then to have a
singleton and snap the references with readResolve -- of course, this
is probably evil if it's mutable, but I've had occasion to want an
immutable singleton, such as

class FooValue {
private static FooValue sentinel = SpecialCaseFooValue.instance;
....
}
class SpecialCaseFooValue extends FooValue {
private static FooValue instance = new SpecialCaseFooValue();
private SpecialCaseFooValue () { ... }
private Object readResolve () { return instance; }
....
}

It's then possible to compare FooValues against FooValue.sentinel
efficiently with == and never get a false negative, including after
data structures containing sentinel have been serialized and
deserialized. (At least, if you don't do anything weird/fancy with
class loaders, just straight Java programming.)

This comes in handy if you want to make e.g. a bigdecimal type with
inf and nan values, or a unique instance of zero. Also for various
data structures where you want to use a sentinel value somewhere but
null is unsuitable. Generally where you want an immutable object that
isn't wastefully duplicated and may be efficiently tested for.

The primary non-evil use of a mutable singleton, for some kind of
caching or logging interface, is also best treated similarly. All of
its fields should be transient, so it doesn't take up wasteful amounts
of space when serialized, and it should have a readResolve to coerce
references to the current runtime's instance on read. That's if you
can't avoid having references to the cache, logger, or whatever in
serializable objects. If you can, don't even make it serializable.
(This is quite unlike the special/sentinel value case, which probably
must be serializable as it likely occurs in data structures or
numerical stuff that needs to be serialized without bits going
missing.)
 
T

Twisted

class SpecialCaseFooValue extends FooValue {
private static FooValue instance = new SpecialCaseFooValue();
private SpecialCaseFooValue () { ... }
private Object readResolve () { return instance; }
...

Bah -- that should be

class SpecialCaseFooValue extends FooValue {
public static FooValue instance = new SpecialCaseFooValue();
private SpecialCaseFooValue () { ... }
private Object readResolve () { return instance; }
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top