查找序列化对象的serialVersionUID

时间:2009-08-24 12:12:11

标签: java serialization serialversionuid

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

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

9 个答案:

答案 0 :(得分:22)

有一种简单的方法可以找到类的serialversionUID -

假设您有一个类,您忘记提及serialversionUID -

import java.io.Serializable;

public class TestSerializable implements Serializable {

}

就这样做 -

serialver -classpath . TestSerializable

这打印 -

static final long serialVersionUID = 5832063776451490808L;

serialver是一个与JDK一起出现的实用程序

答案 1 :(得分:20)

这对我有用:

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

希望它也能帮到你。

答案 2 :(得分:12)

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

}

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

答案 3 :(得分:5)

存在与序列化位相关联的元数据(如果您愿意,可以使用标题)。如果您知道它在哪个位置(SerialVersionUID与其他信息(如类名)一起写入),您可以从元数据中读取值。

我认为这篇文章可能会对您有所帮助:The Java serialization algorithm revealed

请注意,这些位是“明确地”写入的(除非您明确加密了流),因此您可能需要使用HEX编辑器来查看SerialVersionUID的内容。

答案 4 :(得分:1)

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

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

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

答案 5 :(得分:1)

enter image description here 对于Android开发者来说,

您还可以从“设置”中启用序列化检查 - &gt;编辑 - &gt;检查 - &gt;启用&#34;可序列化的类,没有&#39; serialVersionUID&#39;检查&#34;首先,然后ALT + ENTER,工作室将为您创建serialVersionUID。

答案 6 :(得分:0)

这正是你应该做的 - 指定你自己的static final long serialVersionUID

Serializable的文档中有关于它的部分。

除非你指定了serialVersionUID,否则我不相信除了解释@WMR建议的流之外,还有一种简单的方法可以解决这个问题。

答案 7 :(得分:0)

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

  

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

答案 8 :(得分:0)

获得它的最简单方法(尤其是在难于发现的情况下)是为serialVersionUID定义任何数字,并在反序列化失败时监视stacktrace,它将打印出原始数字。