The serialVersionUID is briefly introduced

SerialVersionUID is a field that comes into play when Java serializes and deserializes objects. Java’s serialization mechanism verifies version consistency by determining the serialVersionUID of a class. During deserialization, the JVM will compare the serialVersionUID in the byte stream sent from the JVM with the serialVersionUID of the corresponding local entity class. If the serialVersionUID is the same, it is considered the same and can be deserialized. Otherwise, the serialVersionUID will be inconsistent. Is InvalidClassException.

Serialization is a means of persisting an object externally. It is widely used in network transmission scenarios, such as Dubbo and other frameworks. Class implements the java.io.Serializable interface to enable its serialization capabilities.

Ali Java specification description

Ali protocol mandatory reminder that changing the serialVersionUID field causes deserialization to fail.

Code demo

The following, through the actual code, to demonstrate the object serialization, deserialization operations.

Introduction of depend on

<dependencies>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.8.1</version>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.6</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>
Copy the code

Commons-lang3 has utility classes for serialization, commons-io for file manipulation, and junit for writing unit tests.

serialization

There are user.class as follows:

@Data
@Builder
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    private String username;

}
Copy the code

@data and @Builder are Lombok annotations that automatically generate getters, setters, etc. For those who don’t understand, check out my previous article on this.

The class that needs to be serialized needs to implement the Serializable interface, which is an identity interface that has nothing specific to implement.

Serialization code:

@Test
public void serializeTest(a) throws IOException {
    User user = User.builder().username("happyjava").build();
    byte[] serialize = SerializationUtils.serialize(user);
    FileUtils.writeByteArrayToFile(new File("serialize.txt"), serialize);
}
Copy the code

SerializationUtils is a utility class provided by the Commons-Lang3 package. It provides methods for serialization and deserialization, which we can use directly.

FileUtils is a utility class provided by the Commons-io package, which gives us a very rich IO manipulation utility class.

After executing the method, look at serialize.txt:

This is the object that was serialized and saved externally. We can deserialize it as an object.

deserialization

The deserialization code is as follows:

@Test
public void deserializeTest(a) throws IOException {
    byte[] bytes = FileUtils.readFileToByteArray(new File("serialize.txt"));
    Object object = SerializationUtils.deserialize(bytes);
    System.out.println(object instanceof User);
    User user = (User)object;
    System.out.println(user.getUsername());
}
Copy the code

Here we use FileUtils to read in external files and serialize them into objects using SerializationUtils. Then determine the type of the object after deserialization, and output its username after strong conversion to User, the result is as follows:

Deserialization has been successful

Change the serialVersionUID value to make deserialization abnormal

Now change the serialVersionUID value of User:

@Data
@Builder
public class User implements Serializable {

    private static final long serialVersionUID = 2L;

    private String username;

}
Copy the code

The deserialization method is executed again and the result is as follows:

There is an InvalidClassException as mentioned at the beginning, and you can see from the exception message that this is caused by an inconsistent serialVersionUID.

org.apache.commons.lang3.SerializationException: java.io.InvalidClassException: cn.happy.User; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
Copy the code

conclusion

Through theory and code demonstrations, we already know that the serialVersionUID field can cause deserialization to fail. Therefore, when upgrading the system, you need to consider whether to change the value of serialVersionUID, because this will cause compatibility issues.