为什么我的班级不可序列化?

时间:2012-02-23 10:34:40

标签: java class serialization object serializable

我有以下课程:

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 - 为什么会这样?所有成员都是可序列化的,为什么我会收到错误?

3 个答案:

答案 0 :(得分:16)

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

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

private static class ImageSignature implements Serializable {

答案 1 :(得分:1)

Java Serialization Spec检查以下信息:

  

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

答案 2 :(得分:1)

要使类Serializable,你应该实现Serlizable接口,它是一个没有方法的标记或标记接口,所以你的类的对象应该seralize

private static class ImageSignature implements Serializable {// code }