web-dev-qa-db-fra.com

Pourquoi une classe interne sérialisable n'est-elle pas sérialisable?

Le code suivant:

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;

    }

}

lève l'exception suivante:

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

Je suppose que la classe interne a un champ TestInnerClass.this qui lui permet un accès privé aux champs et méthodes de TestInnerClass. Déclarer la classe interne statique le résout , mais que faire si InnerClass a besoin de cet accès? Existe-t-il un moyen de sérialiser une classe interne non statique sans la classe englobante, par ex. en faisant référence à la classe externe transient?

edit: par exemple, l'accès à la classe externe pourrait être nécessaire uniquement avant la sérialisation. OK, le compilateur ne peut pas le savoir, mais j’ai pensé que c’est la raison pour laquelle le mot clé transient existe.

19
tb189

et si InnerClass a besoin de cet accès?

Ensuite, il a besoin de l'instance de classe externe et il doit être sérialisé avec la classe interne.

Existe-t-il un moyen de sérialiser une classe interne non statique sans la classe englobante, par ex. en faisant référence à la classe externe transitoire?

Non. Que se passerait-il lorsque vous désérialiseriez une telle classe, puis tenteriez d'appeler une méthode d'instance de la classe externe? Un NullPointerException?

23
Michael Borgwardt

comment rendre TestInnerClass sérialisable?

public class TestInnerClass implements Serializable { }
1
hellojinjie

InnerClass ne peut pas être sérialisé car pour l'instancier (comme requis lors de la désérialisation), vous avez besoin d'une référence à une instance de la classe externe.

Les instances de classes internes ne peuvent exister sans une instance de la classe externe.

c'est à dire

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

Si vous utilisez une classe interne statique, il sera possible de sérialiser la classe interne statique. Les instances de classes internes statiques peuvent être créées de manière autonome.

c'est à dire

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