Поиск serialVersionUID сериализованного объекта

Есть ли способ определить сгенерированный serialVersionUID сериализованного объекта Java?

Проблема заключается в том, что я сериализую объект без явного указания serialVersionUID. Теперь процесс десериализации жалуется на несовместимость классов. Однако я не изменил класс таким образом, чтобы сделать его несовместимым. Поэтому я предполагаю, что достаточно указать serialVersionUID в классе, поскольку он хранится в данных объекта. Для этого мне нужно прочитать serialVersionUID из сериализованных данных.

Ответы

Ответ 1

Вы можете сделать это, расширив ObjectInputStream:

public class PrintUIDs extends ObjectInputStream {

  public PrintUIDs(InputStream in) throws IOException {
    super(in);
  }

  @Override
  protected ObjectStreamClass readClassDescriptor() throws IOException,
      ClassNotFoundException {
    ObjectStreamClass descriptor = super.readClassDescriptor();
    System.out.println("name=" + descriptor.getName());
    System.out.println("serialVersionUID=" + descriptor.getSerialVersionUID());
    return descriptor;
  }

  public static void main(String[] args) throws IOException,
      ClassNotFoundException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    List<Object> list = Arrays.asList((Object) new Date(), UUID.randomUUID());
    oos.writeObject(list);
    oos.close();
    InputStream in = new ByteArrayInputStream(baos.toByteArray());
    ObjectInputStream ois = new PrintUIDs(in);
    ois.readObject();
  }

}

Я считаю, что можно было бы прочитать все сериализованные данные, заменив дескриптор, возвращаемый методом, но я его не пробовал.

Ответ 2

Там есть простой способ узнать serialversionUID класса -

Предположим, у вас есть класс, в котором вы забыли упомянуть serialversionUID -

import java.io.Serializable;

public class TestSerializable implements Serializable {

}

Просто сделайте это -

serialver -classpath . TestSerializable

Это означает, что

static final long serialVersionUID = 5832063776451490808L;

serialver - это утилита, которая поставляется вместе с JDK

Ответ 3

Это работает для меня:

long serialVersionUID = ObjectStreamClass.lookup(YourObject.getClass()).getSerialVersionUID();

Надеюсь, что это тоже поможет.

Ответ 4

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

Я думаю, эта статья может вам помочь: Алгоритм сериализации Java показал.

Обратите внимание, что биты записываются "в ясности" (если вы явно не зашифровали поток), поэтому вам может понадобиться редактор HEX, чтобы узнать, что такое SerialVersionUID.

Ответ 6

Что именно вы должны делать - укажите свой static final long serialVersionUID.

Здесь есть раздел об этом в документах для Serializable.

Если вы не указали serialVersionUID, я не верю, что есть простой способ сделать это иначе, чем расшифровать поток, как предлагает @WMR.

Ответ 7

существует гораздо более простой способ получить serialVersionUID сериализованного объекта - просто десериализуйте его с помощью apache commons serialization utils в том же классе с разной версией uid и прочтите сообщение об исключении, которое будет более или менее:

org.apache.commons.lang.SerializationException: java.io.InvalidClassException: my.example.SerializableClass; локальный класс несовместим: stream classdesc serialVersionUID = -1, локальный класс serialVersionUID = -2

Ответ 8

введите описание изображения здесь для разработчиков Android,

вы также можете включить проверку сериализации из "Настройки" → "Редактор" → "Инспекции" → включить "Сериализуемый класс без" serialVersionUID ", а затем ALT + ENTER, студия создаст для вас serialVersionUID.