Java:什么可以和什么不能序列化?

Mor*_*ayS 24 java serialization marker-interfaces

如果Serializable接口只是一个标记接口,用于传递有关java中类的元数据 - 我有点困惑:

在阅读了java的序列化算法(元数据从下到上,然后是从上到下的实际实例数据)的过程之后,我无法真正理解通过该算法无法处理哪些数据.

简而言之:

  1. 什么数据可能导致NotSerializableException?
  2. 我怎么知道我不应该implements Serializable为我的课程添加条款?

JB *_*zet 13

首先,如果您不打算序列化类的实例,则无需考虑序列化它.只实现你需要的东西,不要试图让你的类可序列化只是为了它.

如果您的对象具有对任何非可序列化对象的引用(传递或直接),并且此引用未使用transient关键字标记,则您的对象将不可序列化.

通常,序列化在以后或其他地方反序列化时无法重用的对象是没有意义的.这可能是因为对象的状态仅在此处有意义(例如,如果它具有对正在运行的线程的引用),或者因为它使用某些资源,如套接字,数据库连接或类似的东西.很多对象不代表数据,不应该是可序列化的.


Mic*_*rek 9

当你在谈论NotSerializableException它时,当你想要序列化一个没有被标记为的对象时就抛出Serializable- 这就是全部,尽管当你扩展非可序列化类并添加Serializable接口时它是完全没问题的.

没有数据无法序列化.

  • 唯一真正理解我意思的人:我不想知道**何时**使用“可序列化”接口。我只是想了解哪些数据是可序列化的,哪些数据不是。如果你们中的一些人(@JB Nizet 等)实际上可以添加一个关于以下内容的小解释:如果任何数据最终是由原语构成的——而且这些是可序列化的——为什么 Java 人要创建这个接口? (2认同)
  • @MordechayS Serializable 是一个标记接口,用于区分您想要序列化的对象和您不想序列化的对象。有许多类型的对象在序列化时没有意义。例如连接/文件等类型的对象。这些代表与特定机器相关的资源,如果序列化就没有任何意义。因此标记界面。 (2认同)

Dan*_*lan 5

你的Serializable类中包含的任何东西都不会Serializable抛出这个异常.您可以使用transient关键字来避免它.

无法序列化的常见示例包括Swing组件和Threads.如果你考虑一下它是有道理的,因为你永远不会反序列化它们并使它有意义.


Sac*_*ade 5

所有原始数据类型和类都可以直接扩展为Serializable,

class MyClass extends Serializable{
}
Run Code Online (Sandbox Code Playgroud)

或间接地

class MyClass extends SomeClass{
}
Run Code Online (Sandbox Code Playgroud)

SomeClass实现Serializable。

可以序列化。可序列化类中的所有字段都被序列化,除了标记为的字段transient。如果可序列化的类包含一个不可序列化的字段(不是原始的,并且不从可序列化的接口扩展),NotSerializableException则将抛出该字段。

回答第二个问题:正如@JB Nizet所说。如果要将类的实例写入某个流,然后仅将其标记为Serializable,否则就不要将其标记为Serializable。