Почему сериализуемый внутренний класс не сериализуем?

Следующий код:

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;

    }

}

выдает следующее исключение:

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

Я предполагаю, что внутренний класс имеет поле TestInnerClass.this, которое позволяет ему получать доступ к полям и методам TestInnerClass. Объявление внутреннего класса static решает его, но что, если InnerClass нуждается в этом доступе? Существует ли способ сериализации нестатического внутреннего класса без охватывающего класса, например. сделав ссылку на внешний класс transient?

edit: например, доступ к внешнему классу может потребоваться только до сериализации. ОК, компилятор не может этого знать, но я подумал, почему существует ключевое слово transient.

Ответ 1

что, если InnerClass нуждается в этом доступе?

Затем ему нужен экземпляр внешнего класса, и он должен быть сериализован вместе с внутренним классом.

Есть ли способ сериализации нестатического внутреннего класса без охватывающего класса, например. путем ссылки на переходный класс внешнего класса?

Нет. Что произойдет при десериализации такого класса, а затем попытаться вызвать метод экземпляра внешнего класса? A NullPointerException?

Ответ 2

как сделать сериализуемым TestInnerClass?

public class TestInnerClass implements Serializable { }

Ответ 3

InnerClass не может быть сериализован, потому что для его создания (как требуется при десериализации) вам нужна ссылка на экземпляр внешнего класса

Экземпляры внутренних классов не могут существовать без экземпляра внешнего класса.

i.e

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

Если вы используете статический внутренний класс, можно будет сериализовать статический внутренний класс. Экземпляры статических внутренних классов могут быть созданы автономными.

i.e

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