2011-02-07 3 views
28

Почему java.util.List не реализует Serializable, тогда как подклассы типа LinkedList, Arraylist do? Разве это не похоже на принципы наследования? Например, если мы хотим, чтобы отправить LinkedList по сети, мы должны написать:Почему java.util.List не реализует Serializable?

new ObjectOutputStream(some inputStream).writeObject(some LinkedList); 

До сих пор так хорошо, но при чтении объекта на другой стороне, мы должны сказать, LinkedList l = (LinkedList)objectInputStream.readObject(); в явной форме вместо List l = (List)objectInputStream.readObject();. Если бы мы когда-либо меняли функциональность записи с LinkedList, чтобы сказать ArrayList, нам также придется изменить часть чтения. Имея List, реализация Serializable решила бы проблему.

+2

Я не думаю, что вторая часть вашего заявления точна, а не то, что у меня была возможность попробовать. Какие ошибки вы получаете? –

ответ

35

List не реализует Serializable, потому что это не ключевое требование для списка. Нет никакой гарантии (или необходимости), чтобы вся возможная реализация List могла быть сериализована.

LinkedList и ArrayList решите это сделать, но это касается их реализации. Другие List реализациями могут быть не Serializable.

+2

В этом случае тот же аргумент может быть применен и к LinkedList, что, будучи очень простым списком, он не может быть сериализуемым, поскольку он не является требованием списка. –

+10

Существует разница в принуждении всех реализаций списка к сериализации, и выбор одной конкретной реализации сериализуется. –

+1

LinkedList - это реализация, на которую разработчики решили предоставить сериализуемое свойство. Если мы следим за вашими рассуждениями, ни один класс не должен реализовывать два интерфейса одновременно ... – Dunaril

3

Поскольку List открыт для реализации подклассами конкретного пользователя, а разработчики могут не обязательно реализовать Serializable. Сериализуемость также не относится к ключевым обязанностям List, поэтому нет причин связывать их вместе.

7

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

Сериализуемое свойство не является частью абстракции List и поэтому не требуется для реализации.

1

Рассмотрите гипотетический ThreadList implements List<Thread>, содержащий список активных тем в данный момент времени. Реализация прозрачно просматривает активные потоки и обеспечивает легкий доступ к ним - для вашего удобства. Должна ли такая реализация быть сериализуемой (забывая, что Thread не сериализуем)?

Лицо, реализующее интерфейс, должно решить, безопасно ли его внедрение для сериализации. List является слишком общим, так как в основном указывается * заказанная коллекция предметов типа T`.

3

No. A LinkedList - это всегда список. Когда вы десериализации связанный список, так как LinkedList является список, вы можете написать

List l = (List) objectInputStream.readObject(); 

Тот факт, что л является фактически LinkedList не является важным. Вы хотели Список, и у вас есть Список.

+0

Вы уверены? Как бы среда выполнения понимала, как десериализовать объект, если вы примените его к несериализуемому интерфейсу? – Dunaril

+1

Листинг происходит после десериализации и, следовательно, здесь не важно -> cast to List is fine – Puce

+3

Среда выполнения знает, как выполнить сеанс сериализации объекта, потому что его сериализованный поток байтов содержит имя класса объекта, который был сериализован. ObjectInputStream создает экземпляр этого класса и заполняет его данными, содержащимися в сериализованном объекте, а затем возвращает их вызывающему. Вызывающий абонент знает, что это был список, который был сериализован, и, таким образом, возвращает возвращаемый объект в список. –

-2

Список расширяет коллекцию, и он ничего не может реализовать, потому что это интерфейс ...

+3

предположительно, что OP означает, что 'List' должен расширять' Serializable' * в дополнение * к 'Collection', тот факт, что он использовал слово« реализация », следует понимать в контексте ... – davin

0

Если список реализует/продолжается Сериализуемым то вы подразумевали контракт, что все классы реализации/подклассы списка также являются Сериализуемыми, которые не всегда верно. Например, посмотрите на реализацию коллекций guava ForwardingListMultimap. Это необязательно, чтобы быть Serializable функционально, и это было возможно только потому, что List не является Serializable.

0

Почему, java.util.List не реализует Serializable ...

Потому что не каждый List осуществление в мире должно быть Serializable.

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

List l = (List) objectInputStream.readObject(); 

Вы пробовали это? Если вы это сделаете, я думаю, вы обнаружите, что он работает.

1

Ваш вопрос, кажется, основан на недоразумении. Для сериализации объекта объект (или его класс) должен реализовать Serializable, но для этого вам не нужно использовать выражение типа Serializable (или некоторый подтип). Совершенно преднамеренно, что метод writeObject имеет тип параметра Object, а не Serializable, а также тип возврата readObject().

Но даже если эти параметры и возвращать типы были Serializable, вам не нужно знать конкретные типы реализации:

ObjectOutputStream stream = ...; 
List myList = ...; 
stream.writeObject((Serializable)myList); 

и

ObjectInputStream stream = ...; 
List myList = (List) stream.readObject(); 

будет работать так же, как он сейчас работает (без Serializable cast).

ObjectInputStream и ObjectOutputStream не заботятся о ваших типах при вызове, они просто смотрят на объект под рукой и его класс.

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