如果Serializable
接口只是用于传递Java类的元数据的标记接口-我有点困惑:
阅读了Java序列化算法的过程(从底部到顶部的元数据,然后从顶部到底部的实际实例数据),我无法真正理解哪些数据不能通过该算法处理。
简而言之:
- 什么数据可能导致
NotSerializableException
? - 我应该如何知道不应该为我的类添加
implements Serializable
子句?
如果Serializable
接口只是用于传递Java类的元数据的标记接口-我有点困惑:
阅读了Java序列化算法的过程(从底部到顶部的元数据,然后从顶部到底部的实际实例数据),我无法真正理解哪些数据不能通过该算法处理。
简而言之:
NotSerializableException
?implements Serializable
子句?首先,如果您不计划序列化类的任何实例,则根本没有必要考虑对其进行序列化。只需实现您需要的内容,不要为了序列化而试图使您的类可序列化。
如果您的对象引用(传递或直接)到任何非可序列化对象,并且此引用未标记为transient
关键字,则您的对象将无法序列化。
通常,对于那些在反序列化后或其他地方无法重用的对象,对它们进行序列化是没有意义的。这可能是因为对象的状态只在此处和现在有意义(例如,如果它引用正在运行的线程),或者因为它使用某些资源,如套接字、数据库连接或类似资源。许多对象并不代表数据,因此不应该可序列化。
NotSerializableException
时,它会在您想要序列化一个未被标记为Serializable
的对象时抛出 - 就是这样。但是,如果您扩展了不可序列化的类并添加了Serializable
接口,那么就没有问题了。如果您的Serializable
类中包含未序列化的内容,将会抛出此异常。您可以使用transient
关键字来避免该异常。
常见的无法序列化的内容包括Swing组件和线程。如果您考虑一下,这是有道理的,因为您永远无法反序列化它们并使其有意义。
class MyClass extends Serializable{
}
class MyClass extends SomeClass{
}
SomeClass实现了Serializable接口。
可以被序列化。实现Serializable接口的类中所有字段都会被序列化,除非该字段被标记为transient
。如果一个序列化类中包含了一个不可序列化的字段(非基本类型并且没有实现Serializable接口),那么将抛出NotSerializableException
异常。
对于第二个问题的回答:正如@JB Nizet所说,只有当你打算将一个类的实例写入某个流中时,才需要将该类标记为Serializable,否则永远不要将一个类标记为Serializable。
NotSerializable
异常是在你的可序列化对象中有某些标记为可序列化的内容时抛出的。其中一个这样的情况可能是:
class Super{}
class Sub implements Serializable
{
Super super;
这里没有将super声明为可序列化,因此会抛出NotSerializableException
异常。