Почему сериализуемый внутренний класс не сериализуем? - PullRequest
19 голосов
/ 22 августа 2011

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

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поля и методы.Объявление статического внутреннего класса решает его , но что, если InnerClass нужен этот доступ?Есть ли способ сериализации нестатического внутреннего класса без включающего класса, например, путем ссылки на внешний класс transient?

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

Ответы [ 3 ]

23 голосов
/ 22 августа 2011

что если InnerClass нужен такой доступ?

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

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

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

1 голос
/ 29 июня 2017

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

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

т.е.

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

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

т.е.

OuterClass o = new OuterClass();
OuterClass.InnerClass i = new OuterClass.InnerClass();
1 голос
/ 22 августа 2011

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

public class TestInnerClass implements Serializable { }
...