为啥我的课程不可序列化?

Posted

技术标签:

【中文标题】为啥我的课程不可序列化?【英文标题】:Why is my class not serializable?为什么我的课程不可序列化? 【发布时间】:2012-03-13 18:06:37 【问题描述】:

我有以下课程:

import java.awt.Color;
import java.util.Vector;

public class MyClass 

    private ImageSignature imageSignature;

    private class ImageSignature implements Serializable 
        private static final long serialVersionUID = -6552319171850636836L;
        private Vector<Color> colors = new Vector<Color>();

        public void addColor(Color color) 
            colors.add(color);
        

        public Vector<Color> getColors() 
            return colors;
        
    

    // Will be called after imageSignature was set, obviously
    public String getImageSignature() 
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(imageSignature);
        oos.close();
        return String(Base64Coder.encode(baos.toByteArray()));
    

当我尝试拨打getImageSignature() 时,我收到了NotSerializableException - 这是为什么呢?所有成员都是可序列化的,为什么会出现这个错误?

【问题讨论】:

颜色是 java.awt.Color 类型的吗? java.awt.Colorjava.util.Vector 测试了你的代码,它没有任何问题。您是否在启动前清理并重建了整个项目? 我也无法重现这个。您能否提供一个完整的、可运行的示例来演示该问题? 好吧,我想我在省略外部类时犯了一个错误……我更新了问题,也许现在它更有意义了? 【参考方案1】:

ImageSignature 的每个实例都有对 MyClass 封闭实例的隐式引用,而MyClass 不可序列化。

要么使MyClass可序列化,要么声明ImageSignature静态:

private static class ImageSignature implements Serializable 

【讨论】:

你的意思是类本身是静态的还是MyClassprivate属性? @FlorianPeschka:我的意思是private static class ImageSignature implements Serializable ...【参考方案2】:

查看Java Serialization Spec的以下信息:

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

【讨论】:

【参考方案3】:

要使类 Serializable 你应该实现 Serlizable 接口,它是一个没有方法的标记或标签接口,因此你的类的对象应该序列化

private static class ImageSignature implements Serializable // code 

【讨论】:

以上是关于为啥我的课程不可序列化?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 MicroBatchReader 必须是可序列化的?任务不可序列化错误

为啥类的一个不可序列化的静态字段在实例被序列化时会抛出 NotSerializableException?

想知道为啥空的内部迭代器会导致 mapPartitionsWithIndex 出现不可序列化的异常

为啥我的pr建序列会有白边?

如何处理 Findbugs“可序列化类中的非瞬态不可序列化实例字段”?

为啥我不应该让一个类可序列化?