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

时间:2013-05-31 06:32:55

标签: java serialization marker-interfaces

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

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

简而言之:

  1. 哪些数据可能会导致NotSerializableException
  2. 我怎么知道我不应该为我的班级添加implements Serializable条款?

9 个答案:

答案 0 :(得分:13)

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

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

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

答案 1 :(得分:8)

当你谈论NotSerializableException当你想要序列化一个没有被标记为Serializable的对象时,它就抛出了 - 尽管你扩展了非可序列化的类,并且添加了{ {1}}界面非常好。

没有无法序列化的数据。

答案 2 :(得分:5)

Serializable类中包含的Serializable类不是transient会抛出此异常。您可以使用{{1}}关键字来避免此问题。

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

答案 3 :(得分:4)

所有原始数据类型和类都直接扩展Serializable

class MyClass extends Serializable{
}

或间接

class MyClass extends SomeClass{
}

SomeClass实现Serializable。

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

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

答案 4 :(得分:3)

您需要处理自己对象的序列化。

Java将为您处理原始数据类型。

更多信息:http://www.tutorialspoint.com/java/java_serialization.htm

答案 5 :(得分:2)

当序列化中的某些内容标记为可序列化时,抛出

NotSerialisable异常。其中一个案例可能是:

class Super{}
class Sub implements Serializable
{
Super super;

这里super不会被提及为serializable,因此会抛出NotSerializableException

答案 6 :(得分:1)

  

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

对此的答案是某些系统级类,如Thread,OutputStream及其子类,这些类不可序列化。对oracle文档进行了很好的解释:http://www.oracle.com/technetwork/articles/java/javaserial-1536170.html

以下是摘要:

  

另一方面,某些系统级类(如Thread,OutputStream及其子类和Socket)不可序列化。实际上,如果它们是没有任何意义的话。例如,在我的JVM中运行的线程将使用我系统的内存。坚持它并试图在你的JVM中运行它根本就没有意义。

答案 7 :(得分:0)

更实际的是,没有对象可以序列化(通过Java的内置 机制)除非它的类实现Serializable接口。 作为这样一个类的实例并不是一个充分的条件, 但是:对于要成功序列化的对象,它也必须是 是的,它所持有的所有非瞬态引用必须为null或引用 可序列化的对象。 (请注意,这是一个递归条件。) 原始值,空值和瞬态变量不是问题。 静态变量不属于单个对象,因此它们不属于单个对象 提出一个问题。

一些常见的类是可靠的序列化安全的。字符串是 可能在这里最值得注意,但所有原始的包装类 类型也很安全。基元数组是可靠的可序列化的。 如果所有元素都可以序列化,则可以序列化引用类型的数组 序列

答案 8 :(得分:0)

  

哪些数据可能导致NotSerializableException?

在Java中,我们序列化对象(已经实现了 Serializable接口的Java类的实例)。所以很明显,如果一个类没有实现 Serializable接口,它就不能被序列化(那么在那种情况下会抛出 NotSerializableException )。

Serializable接口只是一个 marker-interface ,在某种程度上我们可以说它只是一个类的标记,而且只是告诉JVM该类可以被序列化。

  

我怎么知道我不应该添加工具    我的班级的Serializable子句?

这一切都取决于你的需要。

  1. 如果要将 Object 存储在数据库中,则可以  将它序列化为一个字节序列并将其存储在  数据库作为持久数据。

  2. 您可以序列化 Object 以供其他JVM工作使用 在不同的机器上。