Бинарные имена анонимных классов - PullRequest
3 голосов
/ 05 октября 2009

У меня следующая проблема:

1) Существует некоторый абстрактный класс A с несколькими анонимными подклассами, хранящимися в статических полях A. Между двумя анонимными подклассами существует циклическая зависимость. Код этого абстрактного класса похож на следующий:

class A implements Serializable
{ 
    public static final A _1 = new A() {
        public A foo()
        {
            return _2;
        }
    };

    public static final A _2 = new A() {
        public A foo()
        {
            return _1;
        }
    };

    public static final A _3 = new A() {
        public void bar()
        {
            // do something
        }
    };
}

2) На экземпляры класса A ссылаются другие объекты, которые используются в сериализации. Есть некоторые объекты, которые предварительно сериализованы разработчиками и затем включены в выпуск в виде двоичных данных.

После некоторого рефакторинга класса A двоичные имена анонимных подклассов были изменены в сборках выпуска. Я думаю, что это может быть связано с разницей версий компилятора Java. Из файлов .class, созданных на моем компьютере, я вижу, что анонимные подклассы A, хранящиеся в полях _1, _2 и _3, имеют имена A $ 1, A $ 2 и A $ 3 соответственно, но из файлов .class, взятых из сборки выпуска, я вижу, что Анонимные подклассы A, хранящиеся в полях _1, _2 и _3, имеют имена A $ 2, A $ 3 и A $ 1 соответственно. Из-за этого предварительно сериализованные данные стали непригодными для использования, и мне нужно как-то это исправить.

Существуют ли какие-либо спецификации для компиляторов java или JVM, в которых будет указано, какие двоичные имена следует ожидать для моих анонимных классов? В JLS говорится, что именем анонимного класса должно быть имя включающего класса, знак «$» и непустая последовательность цифр без каких-либо ограничений для этих последовательностей.

Я считаю, что мне не следует полагаться на внутренние имена анонимных классов, я также знаю «правильные» способы решения этой проблемы, например, создание предварительно сериализованных данных на сервере сборки. Жаль, что сейчас у нас не так много времени, поэтому я хочу знать, откуда возникает эта разница в именах, чтобы я мог решить эту проблему сейчас.

Ответы [ 3 ]

4 голосов
/ 05 октября 2009

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

  1. если вы хотите, чтобы у ваших классов было хорошо известное имя ... ну, анонимный - это противоположность именованного класса! ; -)
  2. предсериализация и доставка объектов в виде двоичных данных - опасный выбор , и вы его укусили (во время рефакторинга, но я считаю, что это может произойти во многих других условиях). Сериализованные данные обычно рассматриваются как кратковременное решение в Java, которое длится несколько секунд. Многие другие варианты доступны для длительного хранения.

Теперь, если меня попросят решить вашу кратковременную проблему, единственный подход, который я вижу, - восстановить ваши классы до состояния, совместимого с предыдущей версией. Если разница, о которой вы упоминаете, является единственной разницей, я считаю, что определение анонимных классов в том же порядке, что и раньше, стоит попробовать ! Также позаботьтесь о том, чтобы ссылки были обращены назад (к классу ранее в файле), а не вперед (к классу позже в файле).

1 голос
/ 05 октября 2009

Ваш компилятор не выдал никаких предупреждений?

Я считаю, что вы можете читать данные, не полагаясь на анонимные имена классов в текущем коде, переопределив ObjectInputStream.readClassDescriptor. Заменить дескриптором "совместимого" класса. Нет гарантий, что это сработает, но, возможно, стоит попробовать, если ваши данные важны.

1 голос
/ 05 октября 2009

Единственная причина, по которой я могу догадаться, почему это терпит неудачу, состоит в том, что новая версия Java переупорядочивает имена классов, потому что вы ссылаетесь на _2 в _1. Тем не менее, я не думаю, что вы можете полагаться на имена, поскольку Java не дает никаких гарантий, в каком порядке она будет обрабатывать поля класса (и, следовательно, последовательность, в которой она будет создавать внутренние классы).

Но я думаю, что ваша проблема в другом. Какую ошибку вы получаете?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...