静态内部类的序列化

Posted

技术标签:

【中文标题】静态内部类的序列化【英文标题】:Serialization of static inner class 【发布时间】:2012-04-09 13:41:09 【问题描述】:

我们可以在 Java 中序列化一个静态内部类吗?类本身在这里被声明为静态的。

【问题讨论】:

好吧,当你……尝试一下会发生什么? 当我这样做时,我的应用程序运行良好。但是,为了发生这种情况,我正在序列化内部类和外部类,这对我来说不是必需的,但我知道如果内部类被序列化,那么外部类必须被序列化。而且,我对静态类是否可以序列化有一些疑问。 外部类与static内部类的序列化无关。 '静态内部类'在术语上是矛盾的。嵌套类是要么“静态”或“内部”。 【参考方案1】:

在这方面,静态内部类与***类没有什么不同:如果它被声明为实现Serializable(或者是声明为实现Serializable 的类的子类),则它可以被序列化。此外,与***类一样,在运行时序列化期间遇到的所有对象都必须可序列化以避免NotSerializableException。由于内部类是static,因此外部类的性质与此无关。

【讨论】:

谢谢大家。我从你们那里得到了我需要的东西。【参考方案2】:

@Tinkerbel 需要注意的一点 -

序列化静态嵌套类没问题,但什么时候(将来) 如果静态内部类曾经被移动到不同的外部类,那么反序列化旧对象是一个问题。

所有字段都指定为默认/空。

【讨论】:

如果有人能解释为什么会有所帮助?我观察到了这一点,但我没有一个非常令人信服的理由......听起来每当一个包被改变时,这应该发生【参考方案3】:

现在看来答案可能因 Java 版本而异。

JDK 7 中的序列化规范说:

注意 - 强烈建议不要序列化内部类(即不是静态成员类的嵌套类),包括本地和匿名类,原因有几个。因为在非静态上下文中声明的内部类包含对封闭类实例的隐式非瞬态引用,所以序列化这样的内部类实例也会导致其关联的外部类实例的序列化。由 javac(或其他 JavaTM 编译器)生成的用于实现内部类的合成字段是依赖于实现的,并且可能因编译器而异;此类字段的差异可能会破坏兼容性并导致默认 serialVersionUID 值冲突。分配给本地和匿名内部类的名称也取决于实现,并且可能因编译器而异。由于内部类不能声明编译时常量字段以外的静态成员,因此它们不能使用 serialPersistentFields 机制来指定可序列化字段。最后,因为与外部实例关联的内部类没有零参数构造函数(此类内部类的构造函数隐式接受封闭实例作为前置参数),它们无法实现 Externalizable。然而,上面列出的问题都不适用于静态成员类。

根据在 Oracle 和 IBM JDK 1.7 版本之间序列化对象的经验,我可以告诉您它并不总是有效。我不能肯定它总是失败,但你肯定不能指望它工作。

在我的应用程序中没有失败的代码路径在 JDK 1.5 上运行了 5 年,在生产中运行良好,我在之前的序列化文档中没有看到与当前语句类似的任何内容。所以,Java 大神们似乎在 JDK 7 中允许使用这种代码模式。

【讨论】:

这与指定静态内部类的问题无关。

以上是关于静态内部类的序列化的主要内容,如果未能解决你的问题,请参考以下文章

java内部类的静态嵌套类

内部类之静态内部类

静态内部类

内部类和静态内部类有什么区别?

java内部类可以访问外部类的静态方法吗

静态内部类和非静态内部类的区别