serialversionuid là gì

Deft February 26, 2021

SerialVersionUID là 1 tính chất quyết định danh người sử dụng vô serialize/deserialize một object của một class implement Serializable interface.

Bạn đang xem: serialversionuid là gì

Trong nội dung bài viết này tất cả chúng ta tiếp tục bàn luận về phong thái dùng serialVersionUID và trải qua những ví dụ rõ ràng nhằm hoàn toàn có thể làm rõ rộng lớn về nó.

Serial Version UID

Nói một cơ hội giản dị và đơn giản, tất cả chúng ta dùng tính chất serialVersionUID nhằm ghi ghi nhớ những phiên phiên bản của một Serializable class (class implement Serializable interface) nhằm xác minh một object được tuần tự động hoá trước ê đem tương quí với Serializable class ở phiên phiên bản thời điểm hiện tại hay là không.

Các tính chất serialVersionUID của những class không giống nhau song lập, ko liên qua quýt cho tới nhau. Do ê, những class không giống nhau hoàn toàn có thể đem nằm trong độ quý hiếm serialVersionUID.

Để làm rõ rộng lớn, tất cả chúng ta tiếp tục ví dụ như về AppleProduct dùng tính chất serialVersionUID nhằm quyết định danh và đánh giá sự tương quí với những object được tuần tự động hoá.

public class AppleProduct implements Serializable {

    private static final long serialVersionUID = 1234567L;

    public String headphonePort;
    public String thunderboltPort;
}

Tiếp bám theo, khái niệm những util class, vô ê một class dùng làm tuần tự động hoá AppleProduct object sang trọng String và một class dùng làm giải thuật String sang trọng AppleProduct object.

public class SerializationUtility {

    public static void main(String[] args) {
        AppleProduct macBook = new AppleProduct();
        macBook.headphonePort = "headphonePort2020";
        macBook.thunderboltPort = "thunderboltPort2020";

        String serializedObj = serializeObjectToString(macBook);
 
        System.out.println("Serialized AppleProduct object to tát string:");
        System.out.println(serializedObj);
    }

    public static String serializeObjectToString(Serializable o) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(o);
        oos.close();
        
        return Base64.getEncoder().encodeToString(baos.toByteArray());
    }
}

Sau Khi chạy SerializationUtility.java, chúng tao sẽ có được một String là sản phẩm của việc tuần tự động hoá AppleProduct object.

Serialized AppleProduct object to tát string:
rO0ABXNyACljb20uYmFlbGR1bmcuZGVzZXJpYWxpemF0aW9uLkFwcGxlUHJvZHVjdAAAAAAAEta
HAgADTAANaGVhZHBob25lUG9ydHQAEkxqYXZhL2xhbmcvU3RyaW5nO0wADmxpZ2h0ZW5pbmdQb3
J0cQB+AAFMAA90aHVuZGVyYm9sdFBvcnRxAH4AAXhwdAARaGVhZHBob25lUG9ydDIwMjBwdAATd
Gh1bmRlcmJvbHRQb3J0MjAyMA== (1)

Sau ê dùng String(1) kể từ sản phẩm bên trên thực hiện thông số nguồn vào mang đến DeserializationUtility class, tất cả chúng ta tiếp tục giải thuật được String sang trọng AppleProduct object như ban đầu

public class DeserializationUtility {
 
    public static void main(String[] args) {
 
        String serializedObj = (1)
        System.out.println(
          "Deserializing AppleProduct...");
 
        AppleProduct deserializedObj = (AppleProduct) deSerializeObjectFromString(
          serializedObj);
 
        System.out.println(
          "Headphone port of AppleProduct:"
            + deserializedObj.getHeadphonePort());
        System.out.println(
          "Thunderbolt port of AppleProduct:"
           + deserializedObj.getThunderboltPort());
    }
 
    public static Object deSerializeObjectFromString(String s)
      throws IOException, ClassNotFoundException {
  
        byte[] data = Base64.getDecoder().decode(s);
        ObjectInputStream ois = new ObjectInputStream(
          new ByteArrayInputStream(data));
        Object o = ois.readObject();
        ois.close();
        return o;
    }
}

Output

Deserializing AppleProduct...
Headphone port of AppleProduct:headphonePort2020
Thunderbolt port of AppleProduct:thunderboltPort2020

Bây giờ, demo sửa đổi serialVersionUID trong AppleProduct class trở nên một độ quý hiếm không giống và giải thuật lại bằng phương pháp chạy lại DeserializationUtility class.

Deserializing AppleProduct...
Exception in thread "main" java.io.InvalidClassException: com.baeldung.deserialization.AppleProduct; local class incompatible: stream classdesc serialVersionUID = 1234567, local class serialVersionUID = 7654321
	at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:616)
	at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1630)
	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1521)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1781)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
	at com.baeldung.deserialization.DeserializationUtility.deSerializeObjectFromString(DeserializationUtility.java:24)
	at com.baeldung.deserialization.DeserializationUtility.main(DeserializationUtility.java:15)

Như vậy, với việc tất cả chúng ta sửa đổi độ quý hiếm của serialVersionUID, sản phẩm của String được tuần tự động hoá trước với độ quý hiếm serialVersionUID cũ sẽ không thể tương quí với AppleProduct thời điểm hiện tại với serialVersionUID đã và đang được thay cho thay đổi.

Nếu serialVersionUID không được hướng dẫn và chỉ định trong số Serializable class, JVM tiếp tục tự động hóa đưa đến một và đặt điều mang đến class. Tuy nhiên, tất cả chúng ta nên hỗ trợ độ quý hiếm serialVersionUID Khi tổ chức thực hiện những Serializable class và update độ quý hiếm serialVersionUID Khi đem những thay cho thay đổi rộng lớn bên trên class.

Các thay cho thay đổi tương thích

Việc sửa đổi những Serializable class đồng nghĩa tương quan với cấu tạo của chính nó ở thời điểm hiện tại tiếp tục không giống với vượt lên khứ. Do vậy những object được tuần tự động hoá trước ê sẽ không còn thể giải thuật lại với cấu tạo mới mẻ này vì thế bọn chúng trọn vẹn không giống nhau.

Xem thêm: montage là gì

Tuy nhiên, vẫn đang còn những tình huống tất cả chúng ta thay cho thay đổi cấu tạo của Serializable class mà bọn chúng vẫn tương quí với cấu tạo cũ.

Giả sử tất cả chúng ta thêm 1 tính chất mới nhất lightningPort vào ProductApple class.

public class AppleProduct implements Serializable {
//...
    public String lightningPort;
}

Vì tất cả chúng ta một số bí quyết nhỏ một tính chất mới nhất vô AppleProduct class, vậy nên ko đề xuất tất cả chúng ta cần update độ quý hiếm của serialVersionUID. Vì vô quy trình giải thuật những object được tuần tự động hoá trước ê, tính chất lightningPort sẽ không tồn tại độ quý hiếm và giản dị và đơn giản là gán độ quý hiếm null mang đến nó, sót lại những tính chất không giống vẫn có mức giá trị ứng.

Giá trị serialVersionUID đem định

Nếu tất cả chúng ta ko hỗ trợ độ quý hiếm serialVersionUID cho một Serializable class. JVM tiếp tục tự động khái niệm độ quý hiếm này trải qua những Điểm lưu ý của class như thương hiệu và loại tài liệu của những tính chất,thương hiệu class, v.v.

Giả sử tất cả chúng ta đem DefaultSerial ko hỗ trợ độ quý hiếm mang đến serialVersionUID.

public class DefaultSerial implements Serializable {
}

Khi tuần tự động hoá một DefaultSerial object

DefaultSerial instance = new DefaultSerial();
System.out.println(SerializationUtility.serializeObjectToString(instance));

Output

rO0ABXNyACpjb20uYmFlbGR1bmcuZGVzZXJpYWxpemF0aW9uLkRlZmF1bHRTZXJpYWx9iVz3Lz/mdAIAAHhw

Tuy nhiên, Khi tất cả chúng ta sửa đổi bên trên class này sẽ gây nên rời khỏi sự ko tương quí ko xứng đáng đem. Ví dụ tất cả chúng ta tăng tính chất name vô DefaultSerial class.

public class DefaultSerial implements Serializable {
    private String name;
}

Đây sẽ là sự thay cho thay đổi đem tương quí ngược, vớ là cấu tạo thời điểm hiện tại của class vẫn hoàn toàn có thể tương quí với cấu tạo cũ. Do ê những object được tuần tự động hoá tự cấu tạo cũ trọn vẹn hoàn toàn có thể giải thuật lại với cấu tạo mới nhất. Thế nhưng 

Exception in thread "main" java.io.InvalidClassException: 
  com.baeldung.deserialization.DefaultSerial; local class incompatible: 
  stream classdesc serialVersionUID = 9045863543269746292, 
  local class serialVersionUID = -2692722436255640434

Việc này là vì JVM nhận ra được sự thay cho thay đổi những tính chất bên phía trong DefaultSerial class nên độ quý hiếm của serialVersionUID cũng thay cho thay đổi bám theo.

Xem thêm: smoked paprika là gì

Như vậy nếu như dữ thế chủ động khái niệm serialVersionUID thì tất cả chúng ta sẽ sở hữu được toàn quyền trấn áp việc tuần tự động hoá và giải thuật của những Serializable class.

Nguồn

https://www.baeldung.com/java-serial-version-uid