为什么比较器应该实现Serializable接口?

46

刚接触Java,正在开发一个Android应用程序时学习它。我正在实现一个Comparator以对文件列表进行排序,安卓文档,Comparator应该实现Serializable接口:

建议Comparator实现Serializable接口。

这是Serializable接口的链接

我只想对文件列表进行排序。为什么要实现它?或者任何Comparator都应该这样做的原因是什么?


安卓为什么会在意序列化呢? - irreputable
3
为什么你不会在Android上使用序列化? - Thilo
5个回答

58

这不仅限于Android,Java SDK也有同样的建议:

注意: 通常建议比较器也应该实现java.io.Serializable,因为它们可能会被用作可序列化数据结构(如TreeSet、TreeMap)中的排序方法。 为了使数据结构成功序列化,比较器(如果提供)必须实现Serializable。

因此,这个想法是因为TreeMap是可序列化的,并且TreeMap可以包含一个Comparator,所以最好让Comparator也是可序列化的。所有集合中的元素都适用于相同的规则。

除非您以那种方式使用序列化,否则可以安全地忽略此内容。


13

Serializeable 是一个空接口,它不包含任何方法。因此,要实现它,您只需要在类中声明 implements Serializable 即可。这对您来说并不是一个巨大的负担。如果您扩展了 Comparator,甚至不需要实现 Serializable,因为父类已经为您完成了这个任务,然后您无需执行任何操作就可以实现 Serializable

当某个对象实现了 Serializable 接口时,这意味着该对象可以随时转换为字节数组。这用于在互联网上传输,存储在文件中等。粗略地说,序列化工作原理是默认情况下,将对象引用的每个对象都转换为字节数组(即递归调用其上的序列化),然后将这些字节数组连接起来以生成表示整个对象的字节数组。

那么,为什么 Comparator 需要实现 Serializable 呢?假设您希望序列化一个 TreeMap 或其他有序的 Collection。序列化的目标是提供对象的完整表示。像 TreeMap 这样的集合内部有一个 Comparator 对象,因此为了能够生成捕获此类集合的每个方面的字节数组,您需要能够将 Comparator 保存为字节数组。因此,Comparator 需要实现 Serializable,以便其他对象也可以正确序列化。


6
如果你扩展Comparator接口:Comparator是一个接口(并且不继承Serializable)。要实现它,你只需要在类中写上"implements Serializable",但你也需要考虑这样做是否合适。例如,所有实例字段也需要可序列化(或者你需要采取某些措施)。 - Thilo

10

这里有一些帮助:http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html

注意:通常最好让比较器实现java.io.Serializable接口,因为它们可能被用作可序列化数据结构(如TreeSet、TreeMap)中的排序方法。为了使数据结构能够成功序列化,比较器(如果提供)必须实现Serializable接口。


3
要在Java中序列化一个对象,需要满足以下两个条件:
  1. 该实例所属的类必须实现java.io.Serializable接口。
  2. 该类的成员变量应该是可序列化的。如果其中一个或多个成员变量不需要被序列化,则应将其标记为transient。

当任何数据结构使用比较器(Comparator),并且您希望该数据结构可以被序列化时,第2点(上述提到)要求比较器实现Serializable接口。


0
我在Java 5 API中看到过这样的内容: 链接到Java 5 APT,其中指出通过实现Comparator接口并不意味着要实现Serializable接口,因此,我们必须明确地注意,在某些自定义创建的Comparator类中获取Serializable接口。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接