views:

130

answers:

4

I have a class which is intended for immutable use, hence I would like to label all the fields final.

However the class is serialized and deserialized to send over the network. For this to work an empty constructor is required. This prevents me creating the final fields.

I'm sure this is a fairly common problem but I can't find a solution. How should I proceed?

+2  A: 

A no-arg constructor is not required. The most derived non-serialisable class does need a no-arg constructor available to the least-most derived serialisable class.

If you need to mutate fields inside a readObject, then use a serial proxy through readResolve and writeReplace.

Tom Hawtin - tackline
+1  A: 

In the typical serialization case, it is not required that class have an empty constructor or non-final fields to be serializable.

Now, if you have to do your own serialization, or you need to subclass a class that doesn't implement Serializable, that is a different story.

So you need to provide some more details of how you are having a problem.

Yishai
Thanks, I was using the typical method of serialization but had always supplied an empty constructor as that was how I thought it worked.
Pool
+2  A: 

This issue is an open bug on the Java language. (Note that this only applies if you have to do the serialization manually, such as with readObject)

Steven Schlansker
From the evaluation: "the problem applies to final instance fields other than the class's serializable fields" so in the standard case it works fine. Nick seems to be doing something different.
Yishai
Ah yes, I should add a disclaimer that this only applies if you have to hook into readObject or something like that.
Steven Schlansker
+2  A: 

To echo what has been said, no-arg constructors are not a requirement if you are taking the route of implementing the java.io.Serializable interface. Take a look at the java.lang.Integer source code for example, a simple serializable/immutable class that has two constructors: one that takes an int, and one that takes a String. Source code: http://www.docjar.com/html/api/java/lang/Integer.java.html. Javadoc: http://java.sun.com/javase/6/docs/api/java/lang/Integer.html.

Also depending on the complexity of your class and what you are doing, you could consider implementing serialization via the java.io.Externalizable interface (although some consider it outdated, and it DOES require a no-arg constructor). Here's an overview on SO: http://stackoverflow.com/questions/817853/what-is-the-difference-between-serializable-and-externalizable-in-java, and here's the official Java tutorial: http://java.sun.com/docs/books/tutorial/javabeans/persistence/index.html.

Chris B.