用于集合的 SerializedWrappers 是一个坏主意吗?
有很多集合不是可序列化
的。一些特别烦人的问题是 HashMap
上的 keySet
和 values
集合(请参阅 JDK bugs 4756277 和 4501848 用于该讨论)。
如果我需要序列化这些集合之一,建议的解决方法是修改另一个实现了 Serialized
的集合中的内容并发送它。例如:
Set<T> realSet = myHashMap.keySet();
Set<T> toSerialize = new HashSet<T>(realSet);
我不喜欢这样做的开销,特别是考虑到序列化操作的实现通常就像写出大小并在集合中迭代一次一样简单。
这让我想到了一个可序列化包装类的想法,它实现了这种简单的序列化形式,并且仅具有对委托的瞬时引用,本着 synchronizedSet
和朋友的精神。像这样,实现仅依赖于 size()
和 iterator
,并使用 readResolve
反序列化以给出 HashSet,说。
这个感觉有点脏。真正的漏洞在哪里?
- 无法根据与
HashSet
(TreeSet
、IdentityHashMap
等)的等价关系处理集合。我不认为这太重要,我们只是没有指定这些类型的集合的结果,就像其他地方看到的那样。 - 是否有关于版本 uid 的序列化问题会阻止其工作?即将尝试...
- 这不会遵守反序列化时的规范,例如 HashMap#keySet(),因为它不是映射的实时视图。是否可以仅指定它是序列化时映射的静态视图?
There are plenty of collections that are not Serializable
. Some particularly annoying ones are the keySet
and values
collections on a HashMap
(see JDK bugs 4756277 and 4501848 for that discussion).
If I need to serialize one of these collections, one suggested workaround is to whack the contents in another collection that does implement Serializable
and send that instead. For example:
Set<T> realSet = myHashMap.keySet();
Set<T> toSerialize = new HashSet<T>(realSet);
I don't like the overhead of this, especially when considering that the implementation of the serialization operation is typically as simple as writing out the size and iterating once through the set.
This leads me to the idea of a serializable wrapper class that implements this simple serialization form and has only a transient reference to the delegate, in the spirit of synchronizedSet
and friends. Something like this, with the implementation depending only on size()
and iterator
, and deserializing with readResolve
to give a HashSet
, say.
This feels slightly dirty. Where are the real holes?
- fails to handle collections based on an equivalence relation to that of
HashSet
(TreeSet
,IdentityHashMap
etc.). I can't see that this matters too much, we just don't specify results on these types of collections, as is seen elsewhere. - are there serialization gotchas about version uid that will prevent this from working? About to try it...
- this would not respect the specification of, say, a
HashMap#keySet()
when deserialized, in that it would not be a live view of the mappings. Is it ok just to specify that it's a static view of the mappings at the time at which it was serialized?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
过早优化的开销。有 99% 的把握,使用复制构造函数不会成为程序的性能瓶颈。在分析器告诉您情况之前,您甚至不应该开始这种考虑。
Premature optimization. With 99% certainty, using the copy constructor will not be the performance bottleneck in your program. You should not even begin this kind of consideration until a profiler tells you what is.
在类似的情况下,我选择了
http://code.google.com/p/protobuf/
它实施起来非常简单,并且有一些直接的好处。这个想法是,不是直接序列化对象,每个对象都包装一条消息,所有消息都是一组变量及其值。然后序列化该消息。要恢复对象,只需将消息传递给构造函数并设置其状态即可。
protobuf 将序列化与重新序列化(erm 和序列化数据所用的语言)解耦
另一方面,就数据大小而言,Java 序列化是荒谬的。 Java 对对象包名称进行编码,因此如果您像在 Java 中那样使用命名空间,则 com.thisismyobject.manthesecharactersareaddingup 会嵌入到每个序列化对象的每次传输中,因此假设您在序列化对象中嵌套了对象,则其大小几乎是 20 倍实际有用的数据!
In a similar situation I went with
http://code.google.com/p/protobuf/
It is very simple to implement and has a few immediate benefits. The idea is that instead of serializing the object directly each object wraps a message, all a message is is a set of variables and their values. Then you serialize the message. To reinstate the object you just pass the message to a constructor and set its state.
protobuf decouples serialization from re-serialization(erm and the language you serialized the data in)
On another note Java serialization in terms of data size is absurd. Java encodes the objects package name so if you use namespaces like you should in Java com.thisismyobject.manthesecharactersareaddingup is embedded in every transmission for every serialized objects so say you had nested objects in the serialized objects is will be almost 20 times the size of the actual useful data!
我认为最好的解决方案是自己实现一些对此类集合进行序列化/反序列化的方法。所以你将独立于java集合框架的变化。
I think the best solution will be to implement some methods for serialization/deserialization of such collections by yourself. So you will be independ from java collections framework's changes.