MrD
MrD

Reputation: 1275

Java: how to ensure serializable collections

In Java, the Collection-interfaces do not extend Serializable for several good reasons. In addition, most common implementations of these interfaces implement Serializable.

So objects which implement one of the Collection-interfaces are serializable if the implementation itself is serializable (which is usually the case) and if the objects in the collection are all serializable.

But how can I ensure that these two conditions are met? I don't want to run into a runtime-error since the compiler could check these conditions. I'm thinking about some obvious interface like (showcase for the List-interface):

public interface SerializableList<T extends Serializable> extends Serializable, List<T> {}

I'm wondering if no one else is facing this problem and came up with this easy solution. Up to now I wasn't able to find any solution or even discussion on this, which makes me doubt on my idea.

Upvotes: 20

Views: 29329

Answers (3)

Gunnar
Gunnar

Reputation: 413

An approach for cloning a collection and contained objects is

import org.apache.commons.lang3.SerializationUtils;
...
ClonedArrayList = SerializationUtils.deserialize(SerializationUtils.serialize(OriginalArrayList))

(for example via using ArrayList<Type>(collection) because SerializationUtils need the Serializable interface)

Regards, Gunnar

Upvotes: 1

jarnbjo
jarnbjo

Reputation: 34313

What you essentially ask for is a type definition joining two types:

<type-def> a = null;

What you need is a replacement of <type-def> with a specification, making sure that the object referenced by a implements both Serializable as well as Collection<? extends Serializable>. Such a type definition is not supported by the Java language.

As you already wrote, the most obvious solution may be to declare your own interface, joining these two other interfaces:

interface SerializableCollection<T extends Serializable> extends Collection<T>, Serializable {}

Seems ok, until you try something like this:

SerializableCollection<String> a = new ArrayList<String>();

This won't however compile. Even if ArrayList<String> implements both Collection<? extends Serializable> and Serializable, the class does not implements SerializableCollection<String>.

Now, you can if you would, circumvent even this problem by declaring a new class:

SerializableArrayList<T extends Serializable> extends ArrayList<T> implements SerializableCollection<T> {}

Now you have essentially combined everything you need and would be able to fulfill the original requirement:

SerializableCollection<String> a = new SerializableArrayList<String>();

Is it worth the effort? In your case, you must decide, but I would say no. My argument is that since the Serializable marker is just a non-formal 'label', ensuring that both your collection and its content implement Serializable still does not guarantee that the collection and its content actually can be serialized.

Upvotes: 11

Tom Hawtin - tackline
Tom Hawtin - tackline

Reputation: 147164

Serializable isn't a great interface. It should have been an annotation, if those were available when it was implemented.

How would you handle a List of a List of something not Serializable. You would need to ensure no object is non-serialisable transitively down the object graph. Not all objects that implement Serializable can actually be serialised.

Upvotes: 7

Related Questions