Chan Chen Coding...

          Understand The SerialVersionUID

          Refer To: http://www.mkyong.com/java-best-practices/understand-the-serialversionuid/

          If you have ever implemented Serializable interface, you must encounter this warning message

          The serializable class xxx does not declare a static final serialVersionUID field of type long

          So…what is serialVersionUID?

          The serialVersionUID is used as a version control in a Serializable class. If you do not explicitly declare a serialVersionUID, JVM will do it for you automatically, based on various aspects of your Serializable class, as described in the Java(TM) Object Serialization Specification.

          1. SerialVersionUID Example

          The above statement is a bit hard to understand at the beginning (at least I did), let start an example to understand how Serializable class use SerialVersionUID to implement version control.

          1.1 Address.java

          A serializable class with a serialVersionUID of 1L.

          import java.io.Serializable;
           
          public class Address implements Serializable{
           
                 
          private static final long serialVersionUID = 1L;
           
                 String street;
                 String country;
           
                 
          public void setStreet(String street){
                     
          this.street = street;
                 }
           
                 
          public void setCountry(String country){
                     
          this.country = country;
                 }
           
                 
          public String getStreet(){
                     
          return this.street;
                 }
           
                 
          public String getCountry(){
                     
          return this.country;
                 }
           
                 @Override
                 
          public String toString() {
                     
          return new StringBuffer(" Street : ")
                     .append(
          this.street)
                     .append(
          " Country : ")
                     .append(
          this.country).toString();
                 }
          }

           

          1.2 WriteObject.java

          A simple class to write / serialize the Address object into a file – “c:\\address.ser”.

          import java.io.FileOutputStream;
          import java.io.ObjectOutputStream;
           
          public class WriteObject{
           
              
          public static void main (String args[]) {
           
                 Address address 
          = new Address();
                 address.setStreet(
          "wall street");
                 address.setCountry(
          "united states");
           
                 
          try{
           
                  FileOutputStream fout 
          = new FileOutputStream("c:\\address.ser");
                  ObjectOutputStream oos 
          = new ObjectOutputStream(fout);   
                  oos.writeObject(address);
                  oos.close();
                  System.out.println(
          "Done");
           
                 }
          catch(Exception ex){
                     ex.printStackTrace();
                 } 
              }
          }

          1.3 ReadObject.java

          A simple class to read / deserialize the Address object from file – “c:\\address.ser”.

          import java.io.FileInputStream;
          import java.io.ObjectInputStream;
           
          public class ReadObject{
           
             
          public static void main (String args[]) {
           
                 Address address;
           
                 
          try{
           
                     FileInputStream fin 
          = new FileInputStream("c:\\address.ser");
                     ObjectInputStream ois 
          = new ObjectInputStream(fin);
                     address 
          = (Address) ois.readObject();
                     ois.close();
           
                     System.out.println(address);
           
                 }
          catch(Exception ex){
                     ex.printStackTrace(); 
                 } 
             }
          }

          2. Testing

          Let do some testing to demonstrate the use of serialVersionUID.

          2.1 Same serialVersionUID

          Same serialVersionUID , there is no problem during the deserialization process

          javac Address.java
          javac WriteObject.java
          javac ReadObject.java
          java WriteObject
          java ReadObject
          Street : wall street Country : united states

          2.2 Different serialVersionUID

          In Address.java, change the serialVersionUID to 2L (it was 1L), and compile it again.

          javac Address.java
          java ReadObject
          java.io.InvalidClassException: Address; local class incompatible: 
          stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
                   
                  at ReadObject.main(ReadObject.java:14)

          The “InvalidClassException” will raise, because you write a serialization class with serialVersionUID “1L” but try to retrieve it back with updated serialization class, serialVersionUID “2L”.

          The serialVersionUID have to match during the serialization and deserialization process.

          3. What’s wrong with the default serialVersionUID?

          If no serialVersionUID is declared, JVM will use its own algorithm to generate a default SerialVersionUID, you can check the algorithm here.

          The default serialVersionUID computation is highly sensitive to class details and may vary from different JVM implementation, and result in an unexpected InvalidClassExceptions during the deserialization process.

          3.1 Client / Server environment

          - Client is using SUN’s JVM in Windows.
          - Server is using JRockit in Linux.

          The client sends a serializable class with default generated serialVersionUID (e.g 123L) to the server over socket, the server may generate a different serialVersionUID (e.g 124L) during deserialization process, and raises an unexpected InvalidClassExceptions.

          3.2 File / Database environment

          - App #1 is using SUN’s JVM in Windows.
          - App #2 is using JRockit in Linux.

          Serialization has allowed to save into a file or database. App #1 stores a serializable class into database by default generated serialVersionUID (e.g 123L), while App #2 may generate a different serialVersionUID (e.g 124L) during deserialization process, and raise an unexpected InvalidClassExceptions.

          You can check here for the List of the JVM implementation.

          4. How to generate serialVersionUID

          You can use JDK “serialver” or Eclipse IDE to generate serialVersionUID automatically, see detail.

          Conclusion

          SUN is highly recommended developers to declare the serialVersionUID in order to avoid the different JVM issue listed above, however I rather recommend you should understand what is serialization, how serialVersionUID implement version control and why your class need to use serialization. Understand the serialVersionUID concept is better than blindfold to any recommendation.

           

           



          -----------------------------------------------------
          Silence, the way to avoid many problems;
          Smile, the way to solve many problems;

          posted on 2012-11-28 12:01 Chan Chen 閱讀(394) 評論(0)  編輯  收藏 所屬分類: Scala / Java

          主站蜘蛛池模板: 洛扎县| 巩留县| 略阳县| 房产| 扎兰屯市| 乌鲁木齐市| 西乌| 霍邱县| 荆门市| 博湖县| 库伦旗| 郑州市| 浮梁县| 峡江县| 南京市| 和林格尔县| 冷水江市| 江津市| 胶州市| 嫩江县| 博野县| 马龙县| 龙川县| 青浦区| 彩票| 新邵县| 韶山市| 密山市| 西充县| 宁都县| 措勤县| 永泰县| 从江县| 阜新市| 南城县| 左贡县| 八宿县| 迁安市| 承德市| 兰坪| 绥芬河市|