简体   繁体   English

为什么可序列化的内部类不可序列化?

[英]Why is a serializable inner class not serializable?

The following code: 以下代码:

public class TestInnerClass {

    public static void main(String[] args) throws IOException {
        new TestInnerClass().serializeInnerClass();
    }

    private void serializeInnerClass() throws IOException {
        File file = new File("test");
        InnerClass inner = new InnerClass();
        new ObjectOutputStream(new FileOutputStream(file)).writeObject(inner);
    }

    private class InnerClass implements Serializable {

        private static final long serialVersionUID = 1L;

    }

}

throws the following exception: 抛出以下异常:

Exception in thread "main" java.io.NotSerializableException: TestInnerClass

I guess the inner class has a TestInnerClass.this field that allows it private access to TestInnerClass 's fields and methods. 我猜内部类有一个TestInnerClass.this字段,允许它私有访问TestInnerClass的字段和方法。 Declaring the inner class static solves it , but what if InnerClass needs this access? 声明内部类静态可以解决它 ,但是如果InnerClass需要这种访问呢? Is there a way to serialize a non-static inner class without the enclosing class, eg by making the reference to the outer class transient ? 有没有办法在没有封闭类的情况下序列化非静态内部类,例如通过引用外部类transient

edit: for example, access to the outer class could be needed only before serialization. 编辑:例如,只有在序列化之前才需要访问外部类。 OK, the compiler cannot know that, but I thought that's why the transient keyword exists. 好的,编译器无法知道,但我认为这就是transient关键字存在的原因。

what if InnerClass needs this access? 如果InnerClass需要这种访问怎么办?

Then it needs the outer class instance, and it must be serialized along with the inner class. 然后它需要外部类实例,并且必须与内部类一起序列化。

Is there a way to serialize a non-static inner class without the enclosing class, eg by making the reference to the outer class transient? 有没有办法在没有封闭类的情况下序列化非静态内部类,例如通过引用外部类瞬态?

No. What would happen when you deserialize such a class and then try to call an instance method of the outer class? 不。当你反序列化这样一个类然后尝试调用外部类的实例方法时会发生什么? A NullPointerException ? NullPointerException

InnerClass cannot be serialised because to instantiate it (as required during deserialization) you need a reference to an instance of the outer class InnerClass无法序列化,因为要实例化它(在反序列化期间需要),您需要引用外部类的实例

Instances of inner classes cannot exist without an instance of the outer class. 没有外部类的实例,内部类的实例不可能存在。

ie

OuterClass o = new OuterClass();
OuterClass.InnerClass o_i = o.new InnerClass();

If you use static inner class, it will be possible to serialise the static inner class. 如果使用静态内部类,则可以序列化静态内部类。 The instances of static inner classes can be created standalone. 静态内部类的实例可以独立创建。

ie

OuterClass o = new OuterClass();
OuterClass.InnerClass i = new OuterClass.InnerClass();

如何使TestInnerClass可序列化?

public class TestInnerClass implements Serializable { }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM