2012-01-12 45 views
2

短的问题:如何发现,在序列化形式的对象的的serialVersionUID。如何发现序列化对象的serialVersionUID的

细节:我在Web应用程序的会话数据库中有一些对象的序列化版本。对于其中一些对象,我没有在源代码中指定serialVersionUID,所以JVM为我创建了一个。我想发现保存的对象的serialVersionUID是什么,以便我可以在我的源文件中对其进行硬编码。

我可以很方便地读取序列化的数据。我已经通过并删除了不会使用当前版本的代码读取的(旧)会话,因此我知道每个序列化对象都与当前代码库匹配。

+0

可能的重复[如何找出序列化Java对象的serialVersionUID?](http://stackoverflow.com/questions/703591/how-can-i-find-out-the-serialversionuid-of-一个序列化的Java对象) – 2012-01-12 18:39:37

+0

答案那里与从源极/类文件生成的serialVersionUID处理更多。我想在现有的序列化对象中发现serialVersionUID。 – Mitch 2012-01-12 18:56:26

回答

2

由于你有数据,则可以简单地看一下八个八位字节以下的流中的类名由类的grammar for Java Serialization

00000000: aced 0005 7372 0003 466f 6f00 0000 0000 ....sr..Foo..... 
00000010: 0000 0102 0001 4c00 066d 794e 616d 6574 ......L..myNamet 
00000020: 0012 4c6a 6176 612f 6c61 6e67 2f53 7472 ..Ljava/lang/Str 
00000030: 696e 673b 7870 7400 044a 6f68 6e   ing;xpt..John 

名称所指示的上面是“富”(没有包),并且serialVersionUID是1L。这里有另外一个例子:

00000000: aced 0005 7372 0011 7374 6163 6b6f 7665 ....sr..stackove 
00000010: 7266 6c6f 772e 466f 6fff ffff ffff 7e3c rflow.Foo.....~< 
00000020: 1802 0001 4c00 066d 794e 616d 6574 0012 ....L..myNamet.. 
00000030: 4c6a 6176 612f 6c61 6e67 2f53 7472 696e Ljava/lang/Strin 
00000040: 673b 7870 7400 044a 6f68 6e    g;xpt..John 

classname是stackoverflow.Foo。该serialVersionUID的是0xff7e3c18由该序列的八位位组指出:

ff ffff fffff 7e3c 18 

现在你要做的就是看看文件格式,找出你的目标是在每一种情况下,读取的serialVersionUID紧随所述的className在语法上面链接。

1

对我来说有效的是使用ObjectStreamClass.lookup(class)。

我运行一个方法,将数据库中的所有会话对象反序列化。然后我对每个我感兴趣的类运行ObjectStreamClass.lookup()。它给了我一个类的ObjectStreamClass对象。 ObjectStreamClass对象包含类名称和serialVersionUID。

我会将其输出并相应地修改我的源文件。

+0

是针对类的代码仍然是相同的,因为它是所有数据库中的序列化实例的? – jbindel 2012-01-12 19:28:33

+0

如果该类实际改变,那么ObjectStreamClass.lookup()可以抛出'java.io.InvalidClassException'如果该类实际改变。如果没有改变,那么做任何这些都没有意义。只需使用'serialver package.Class'。你如何让这个类传递给'lookup()'? – jbindel 2012-01-12 19:37:52

+0

ObjectStreamClass.lookup()对我来说工作得很好。为了获得类的列表,我只是从包中获得了一个文件名列表,我知道它有没有显式serialVersionUID的代码。 – Mitch 2012-01-13 13:46:25