2013-07-23 3 views
11

В Java интерфейсы Collection не распространяют Serializable по нескольким веским причинам. Кроме того, большинство распространенных реализаций этих интерфейсов реализуют Serializable.Java: как обеспечить сериализуемые коллекции

Таким образом, объекты, реализующие один из интерфейсов Collection, могут быть сериализованы, если сама реализация сериализуема (как правило, это так) и, если объекты в коллекции являются сериализуемыми.

Но как я могу обеспечить выполнение этих двух условий? Я не хочу сталкиваться с ошибкой во время выполнения, поскольку компилятор может проверить эти условия. Я думал о каком-то очевидном интерфейсе типа (витрина для списка-интерфейса):

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

мне интересно, если никто не сталкивается с этой проблемой и пришел с этим простым решением. До сих пор я не мог найти никакого решения или даже дискуссии по этому поводу, что заставляет меня сомневаться в моей идее.

+0

Вы можете сделать ссылку 'List' как -' List ', если я правильно понял ваш вопрос. Вам не нужно развертывать собственный интерфейс. –

+0

Компилятор не может проверить это. Каждый класс, реализующий Serializable, может содержать непереходное, несериализуемое поле, что приведет к исключению во время выполнения. И ArrayList может быть сериализуемым, если фактические объекты, которые он содержит, являются сериализуемыми. Если это действительно важно, используйте модульные тесты. –

+1

@RohitJain: Ваше предложение гарантирует только то, что объекты в списке сериализуемы, но не сама реализация List. – MrD

ответ

6

Что вы, по сути просят является определение типа соединения двух типов:

<type-def> a = null;

Что вам нужно, это замена <type-def> со спецификацией, убедившись, что объект на который ссылается a реализует как Serializable, как а также Collection<? extends Serializable>. Такое определение типа не поддерживается языком Java.

Как вы уже писали, самое очевидное решение может быть объявить свой собственный интерфейс, соединяющий эти два другие интерфейсы:

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

вроде нормально, пока вы не попробовать что-то вроде этого:

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

Это, однако, не скомпилируется. Даже если ArrayList<String> реализует как Collection<? extends Serializable>, так и Serializable, класс не реализует SerializableCollection<String>.

Теперь вы можете, если бы вы, обойти даже эту проблему, объявив новый класс:

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

Теперь вы существенно объединены все, что вам нужно, и будет в состоянии выполнить первоначальное требование:

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

Стоит усилий? В вашем случае вы должны решить, но я бы сказал, нет.Мой аргумент заключается в том, что поскольку маркер Serializable - это просто неформальный «ярлык», гарантирующий, что и ваша коллекция, и ее контент реализуют Serializable, все еще не гарантируют, что коллекция и ее содержимое на самом деле могут быть сериализованы.

+1

Спасибо. Я думаю, теперь для меня все ясно. Как вы и JB Nizet заявили, я не могу полагаться, что объекты, реализующие интерфейс Serializable, действительно сериализуемы (очень жаль). Я думаю, что в этом смысл: стоит ли этого? Я подумаю об этом, если это применимо в моем случае. – MrD

6

Serializable не является отличным интерфейсом. Это должно было быть аннотацией, если они были доступны, когда они были реализованы.

Как вы относитесь к List из List чего-то не того Serializable. Вам нужно будет гарантировать, что объект не будет сериализуемым транзитно вниз по графу объектов. Не все объекты, которые реализуют Serializable, могут быть сериализованы.

+0

Так нет способа сделать проверку времени компиляции для этого? –

+0

'интерфейс SerializableCollection > {} 'можно что-то подобное сделать? –

+1

«Список» объектов, которые не являются «Serializable», не могут быть добавлены в 'SerializableList', так как этот' List' не реализует 'Serializable'. Конечно, я мог бы добавить 'ArrayList' (который сериализуем), содержащий некоторые не сериализуемые объекты, но только если я использую его как необработанный. Если он параметризирован, компилятор должен пожаловаться на это. – MrD

0

Подход для клонирования коллекции и содержащиеся объектов

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

(например, с помощью с помощью ArrayList < Тип > (сбор), потому что SerializationUtils нужен Serializable интерфейс)

Привет, Гуннар

Смежные вопросы