Есть ли способ для анонимных внутренних классов в Java «потерять» свою область видимости? - PullRequest
3 голосов
/ 23 марта 2009

Когда я передаю анонимный внутренний класс в функцию, я могу ссылаться на переменные в текущей области изнутри метода этого класса, например:

class Caller {
    private Object callerPrivate;

    // ...

    public void someMethod() {
        final String callerLocal = "Eyes only";

        ISomeInterface anon = new ISomeInterface() {
                                     public void doSomethingInterfacy {
                                         System.out.println(callerPrivate.toString());
                                         System.out.println(callerLocal);
                                     }
                                  };
        // this is some other object that puts ISomeInterfaces in a queue
        // and makes them doSomethingInterfacy later
        myCallManager.enqueue(anon);
    }
}

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

Но что, если, например, очередь сериализуется, программа закрывается и перезапускается, и после этого очередь десериализуется, и элементы в ней должны запускаться, а экземпляр Caller давно исчезнет и будет забыт?

И есть ли другие способы, позволяющие окружающему объекту и анонимному внутреннему классу разделиться так, чтобы вызовы внутри класса anon больше не работали?

Ответы [ 2 ]

6 голосов
/ 23 марта 2009

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

Если вы не хотите, чтобы ваш экземпляр сохранял поля для внешнего this и использовал конечные локальные переменные, используйте (статический) вложенный класс или внешний класс. Для (Java) сериализации вы можете использовать writeReplace для сериализации последовательного прокси-объекта.

2 голосов
/ 23 марта 2009

Не забывайте, что ваш анонимный внутренний класс содержит неявную эту ссылку. т.е. ссылка на окружающий класс.

Так что, если вы сериализуете свой внутренний класс, будет ссылка на ваш внешний класс. Это ясно видно, если вы сериализуете, используя XStream и просматриваете вывод XML.

...