为什么java.util.List
在Serializable
,LinkedList
之类的子类时没有实现Arraylist
?它似乎不是违反继承原则吗?例如,如果我们想通过网络发送链接列表,我们必须写:
new ObjectOutputStream(some inputStream).writeObject(some LinkedList);
到目前为止一切顺利,但在阅读另一方面的对象时,我们必须明确地说LinkedList l = (LinkedList)objectInputStream.readObject();
而不是List l = (List)objectInputStream.readObject();
。如果我们要将书写功能从LinkedList
更改为ArrayList
,我们还必须更改阅读部分。 List
实施Serializable
可以解决问题。
答案 0 :(得分:39)
List
未实现Serializable
,因为它不是列表的关键要求。无法保证(或需要)可以序列化List
的每个可能实现。
LinkedList
和ArrayList
选择这样做,但这是针对其实施的。其他List
实施可能不是Serializable
。
答案 1 :(得分:8)
List是一个接口并使其扩展Serializable意味着List的任何实现都应该是可序列化的。
serializable属性不是List抽象的一部分,因此不应该用于实现。
答案 2 :(得分:3)
因为List
也是由用户特定的子类实现的,并且实现者可能不一定想要实现Serializable
。可序列化也不属于List
的主要职责,因此没有理由将两者联系在一起。
答案 3 :(得分:3)
没有。 LinkedList始终是List。反序列化链表时,由于LinkedList是List,您可以编写
List l = (List) objectInputStream.readObject();
事实上l实际上是一个LinkedList并不重要。你想要一个List,你有一个List。
答案 4 :(得分:2)
考虑假设的ThreadList implements List<Thread>
,其中包含任何给定时间点的活动线程列表。实现透明地浏览活动线程并允许轻松访问它们 - 为了您的方便。这样的实现是否可序列化(忘记Thread
不可序列化?)
由实现界面的人决定她的实现是否可以安全地序列化。 List
过于通用,因为它基本上是对T`类型的项目的有序集合。
答案 5 :(得分:2)
你的问题似乎是基于一种误解。要序列化对象,对象(或其类)必须实现Serializable
,但您不需要使用类型Serializable
(或某些子类型)的表达式来执行此操作。 writeObject
方法的参数类型为Object
而非Serializable
以及readObject()
的返回类型,这是非常有意的。
但即使这些参数和返回类型都是Serializable
,您也不需要知道具体的实现类型:
ObjectOutputStream stream = ...;
List myList = ...;
stream.writeObject((Serializable)myList);
和
ObjectInputStream stream = ...;
List myList = (List) stream.readObject();
现在可以正常工作(没有Serializable演员)。
ObjectInputStream和ObjectOutputStream在调用时根本不关心你的类型,它们只是查看手头的对象及其类。
答案 6 :(得分:0)
如果List实现/扩展Serializable,那么你暗示了List的所有实现类/子类也是Serializable的合同,这并不总是正确的。例如,查看ForwardingListMultimap的guava-collections实现。它不需要在功能上是Serializable,这只是因为List不可序列化。
答案 7 :(得分:0)
为什么java.util.List没有实现Serializable ...
因为并非世界上的每个List
实施都必须Serializable
。
在阅读另一方的对象时,我们必须明确说... 而不是
List l = (List) objectInputStream.readObject();
你试过吗?如果你这样做,我想你会发现它有效。
答案 8 :(得分:-2)
列表扩展了Collection,它无法实现任何东西,因为它是一个接口......