Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 454
MrD Avatar asked Jul 23 '13 08:07

MrD


3 Answers

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.

like image 138
jarnbjo Avatar answered Oct 11 '22 03:10

jarnbjo


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.

like image 35
Tom Hawtin - tackline Avatar answered Oct 11 '22 03:10

Tom Hawtin - tackline


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

like image 38
Gunnar Avatar answered Oct 11 '22 03:10

Gunnar