Struts中private static final long serialVersionUID的作用


今天在看項目源碼的時候發現struts的action里面有

private static final long serialVersionUID = -1672970955045193907L;
這樣的一條語句。

中文搜索之后,全部都是

如果你修改了此類, 要修改此值。否則以前用老版本的類序列化的類恢復時會出錯。為了在反序列化時,確保類版本的兼容性,最好在每個要序列化的類中加入private static final long serialVersionUID這個屬性,具體數值自己定義。


中文的全部都是抄來抄去的答案。這真是叫人惡心。


有趣的事,在外國網站也出現了這樣的狀況。原帖:http://www.coderanch.com/t/596397/java/java/private-static-final-long-serialVersionUID


What is private static final long serialVersionUID = 1L; ???
上面那句話是什么?


Hi Friends,

Can you please tell me the purpose of this line ???

朋友們,

誰能告訴我這段代碼的緣由?


    
SerialVersionUID is an ID which is stamped on object when it get serialized usually hashcode of object, you can use tool serialver to see serialVersionUID of a serialized object . SerialVersionUID is used for version control of object. you can specify serialVersionUID in your class file also. Consequence of not specifying serialVersionUID is that when you add or modify any field in class then already serialized class will not be able to recover because serialVersionUID generated for new class and for old serialized object will be different. Java serialization process relies on correct serialVersionUID for recovering state of serialized object and throws java.io.InvalidClassException in case of serialVersionUID mismatch.


SerialVersionUID,后面簡稱SUID,是當對象序列化的時候對象的一個標識(stamp on 在這里我也不太清楚翻譯成什么好),SUID的值常為該對象的hascode。你可以使用工具serialver查看一個序列化對象的SUID。SUID用於控制對象的版本。你也可以在類文件中指定SUID。不指定SUID的結果就是當你添加或者更改類的域並已經序列化類的時候,類是不能再恢復了,因為新的SUID和之前的SUID不同了。Java的序列化過程依賴於正確的SUID來反序列化已經序列化的對象,如果SUID不匹配,那么就會拋 java.io.InvalidClassException 異常了。


Please don’t simply copy and paste from another website; that may be breach of copyright. That quote is confusing at the best.

An SUID is not a hash of the object, but a hash of its originating class. If the class is updated, for example with different fields, the SUID can change. You have four (at least) possible courses of action:-

  • 1: Leave out the SUID. This tells the runtime that there are no differences between versions of classes when serialising and deserialising.
  • 2: Always write a default SUID, which looks like the heading of this thread. That tells the JVM that all versions with this SUID count as the same version.
  • 3: Copy an SUID from a previous version of the class. That tells the runtime that this version and the version the SUID came from are to be treated as the same version.
  • 4: Use a generated SUID for each version of the class. If the SUID is different in a new version of the class, that tells the runtime that the two versions are different and serialised instances of the old class cannot be deserialised as instances of the new class.


    請不用簡單地從別的網站復制粘貼(一針見血指出上面回答的缺點);這是對版權的破壞,而且這樣的描述最多還是困惑讀者。

    SUID不是一個對象的哈希值(翻譯錯了,公司一個牛逼同事提醒了!),是源類的哈希值。如果類更新,例如域的改變,SUID會變化,這里有4個步驟:

    1.忽略SUID,相當於運行期間類的版本上的序列化和反序列上面沒有差異。

    2.寫一個默認的SUID,這就好像線程頭部。告訴JVM所有版本中有着同樣SUID的都是同一個版本。

    3.復制之前版本類的SUID。運行期間這個版本和之前版本是一樣的版本。

    4.使用類每個版本生成的SUID。如果SUID與新版本的類不同,那么運行期間兩個版本是不同的,並且老版本類序列化后的實例並不可以反序列成新的類的實例。


    第四點才是private static final long serialVersionUID的作用的重點所在。


    Thanks Campbell, will be careful from now on. 

    后面那個直接抄答案的跟上面那位答者致謝。對方也在后面的回復中也豎起大拇指。


    最后總結一下:其實序列化的作用是能轉化成Byte流,然后又能反序列化成原始的類。能在網絡進行傳輸,也可以保存在磁盤中,有了SUID之后,那么如果序列化的類已經保存了在本地中,中途你更改了類后,SUID變了,那么反序列化的時候就不會變成原始的類了,還會拋異常,主要就是用於版本控制。


    這完完全全是和國內這種復制粘貼漫天飛的問答的不同的格調,這正是技術所需要的一種氣氛,一種對更好的答案的追求。

    希望以后國內的技術氛圍也能如此!


  • 注意!

    本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



     
      © 2014-2022 ITdaan.com 联系我们: