查找序列化对象的serialVersionUID

发布于 2024-08-03 04:45:42 字数 265 浏览 9 评论 0原文

有没有办法确定序列化 Java 对象生成的 serialVersionUID

问题是我在没有明确指定 serialVersionUID 的情况下序列化了一个对象。现在,反序列化过程抱怨类不兼容。但是,我没有以使其不兼容的方式更改该类。因此,我认为在类中指定 serialVersionUID 就足够了,因为它存储在对象数据中。为此,我需要从序列化数据中读取 serialVersionUID

Is there a way to determine the generated serialVersionUID of a serialized Java object?

The problem is that I serialized an object without explicitely specifying the serialVersionUID. Now the deserialization process complains about class incompatibilities. However I didn't change the class in a way which would make it incompatible. So I assume that it is enough to specify the serialVersionUID in the class as it is stored in the object data. In order to do this I need to read the serialVersionUID from the serialized data.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

薄暮涼年 2024-08-10 04:45:42

这对我有用:

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

希望它也对你有帮助。

This works for me:

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

Hope it helps you too.

只为守护你 2024-08-10 04:45:42

有一个简单的方法可以找出类的serialversionUID -

假设你有一个忘记提及serialversionUID的类 -

import java.io.Serializable;

public class TestSerializable implements Serializable {

}

只需这样做 -

serialver -classpath . TestSerializable

这个打印 -

static final long serialVersionUID = 5832063776451490808L;

serialver是JDK附带的一个实用程序

There's an easy way to find out serialversionUID of a class-

Suppose you have class in which you have forgotten to mention serialversionUID-

import java.io.Serializable;

public class TestSerializable implements Serializable {

}

Just do this-

serialver -classpath . TestSerializable

This prints-

static final long serialVersionUID = 5832063776451490808L;

serialver is a utility that comes along with JDK

爱她像谁 2024-08-10 04:45:42

您可以通过扩展 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();
  }

}

:相信通过替换方法返回的描述符可以读取所有序列化数据,但我还没有尝试过。

You can do this by extending 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();
  }

}

I believe it would be possible to read all the serialized data by replacing the descriptor returned by the method, but I haven't tried it.

£冰雨忧蓝° 2024-08-10 04:45:42

有与序列化位关联的元数据(如果您愿意,可以是标头)。如果您知道该值位于哪个位置,则可以从元数据中读取该值(SerialVersionUID 与其他信息(例如类名)一起写入此处)。

我认为这篇文章可能对您有帮助:Java 序列化算法揭秘

请注意,这些位是“明文”写入的(除非您显式加密流),因此您可能只需要十六进制编辑器即可查看 SerialVersionUID 是什么。

There is metadata associated with the serialized bits (a header if you like). You can read the value from the metadata if you know at which position it is (the SerialVersionUID is written there along with other info such as the class name).

I think this article might help you: The Java serialization algorithm revealed.

Note that the bits are written "in clear" (unless you encrypted the stream explicitly) so a HEX editor might be all you need to see what is the SerialVersionUID.

草莓味的萝莉 2024-08-10 04:45:42

对象的序列化有一个指定的语法:

参见第 6.4 章
http://java.sun.com/javase/ 6/docs/platform/serialization/spec/serialTOC.html

使用它,您应该能够确定序列化对象的 SerialVersionUID。

There is a specified grammar for the serialization of objects:

See chapter 6.4 in
http://java.sun.com/javase/6/docs/platform/serialization/spec/serialTOC.html

Using this, you should be able to determine the SerialVersionUID of your serialized object.

蔚蓝源自深海 2024-08-10 04:45:42

输入图片此处描述
对于 Android 开发者,

您还可以从“设置”->“启用序列化检查”。编辑->检查->首先启用“不带‘serialVersionUID’检查的可序列化类”,然后按 ALT+ENTER,工作室将为您创建serialVersionUID。

enter image description here
for Android developers,

you can also enable serialization inspection from Settings -> Editor -> Inspections -> enable "Serializable class without 'serialVersionUID' check" first, then ALT+ ENTER, the studio will create serialVersionUID for you.

鲸落 2024-08-10 04:45:42

获取它的最简单方法(尤其是在很难找到的情况下)是为serialVersionUID定义任意数字,并在反序列化失败时监视堆栈跟踪,它将打印出原始版本。

The easiest way to get it (especially on hard to find cases) is to define any number for serialVersionUID and monitor the stacktrace when the deserialization fails, it will print out the original one.

遥远的绿洲 2024-08-10 04:45:42

这正是您应该做的 - 指定您自己的staticfinal longserialVersionUID

文档中有一个关于它的部分 Serialized。

除非您指定了 serialVersionUID ,否则我不认为除了按照 @WMR 建议的方式破译流之外还有其他简单的方法来获取它。

That's exactly what you should do - specify your own static final long serialVersionUID.

There's a section about it in the docs for Serializable.

Unless you've specified a serialVersionUID I don't believe there's an easy way to get it other than deciphering the stream as @WMR suggests.

芸娘子的小脾气 2024-08-10 04:45:42

有更简单的方法来获取序列化对象的serialVersionUID - 只需使用apache commons序列化utils将其反序列化为具有不同序列版本uid的同一类,并读取或多或少的异常消息:

org.apache.commons.lang.SerializationException: java.io.InvalidClassException: my.example.SerializedClass;本地类不兼容:流classdesc serialVersionUID = -1,本地类serialVersionUID = -2

there is much simpler way to get the serialVersionUID of serialized object - just deserialize it with apache commons serialization utils to same class with different serial version uid and read the exception message which will be more or less:

org.apache.commons.lang.SerializationException: java.io.InvalidClassException: my.example.SerializableClass; local class incompatible: stream classdesc serialVersionUID = -1, local class serialVersionUID = -2

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文