2012-01-12 43 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