💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# `serialVersionUID`的用途是什么 > 原文: [https://javabeginnerstutorial.com/core-java-tutorial/use-serialversionuid/](https://javabeginnerstutorial.com/core-java-tutorial/use-serialversionuid/) 在这里,我将讨论在可序列化类中使用的变量`serialVersionUID`的重要性。 下面是一个使您了解变量的确切用法的示例。 ## 示例代码 `Employee.java` ```java package com.jbt; import java.io.Serializable; public class Employee implements Serializable { public String firstName; public String lastName; private static final long serialVersionUID = 5462223600l; } ``` `SerializaitonClass.java`(此类将用于序列化) ```java package com.jbt; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; public class SerializaitonClass { public static void main(String[] args) { Employee emp = new Employee(); emp.firstName = "Vivekanand"; emp.lastName = "Gautam"; try { FileOutputStream fileOut = new FileOutputStream("./employee.txt"); ObjectOutputStream out = new ObjectOutputStream(fileOut); out.writeObject(emp); out.close(); fileOut.close(); System.out.printf("Serialized data is saved in ./employee.txt file"); } catch (IOException i) { i.printStackTrace(); } } } ``` `DeserializationClass.java`(此类将用于反序列化) ```java package com.jbt; import java.io.*; public class DeserializationClass { public static void main(String[] args) { Employee emp = null; try { FileInputStream fileIn = new FileInputStream("./employee.txt"); ObjectInputStream in = new ObjectInputStream(fileIn); emp = (Employee) in.readObject(); in.close(); fileIn.close(); } catch (IOException i) { i.printStackTrace(); return; } catch (ClassNotFoundException c) { System.out.println("Employee class not found"); c.printStackTrace(); return; } System.out.println("Deserializing Employee..."); System.out.println("First Name of Employee: " + emp.firstName); System.out.println("Last Name of Employee: " + emp.lastName); } } ``` 现在执行“`SerializationClass.java`”,然后执行“`DeserializationClass.java`”。 它将首先创建一个具有`Employee`对象状态的文件,然后在反序列化时从同一文件创建一个对象。 输出将如下所示。 ```java Serialized data is saved in ./employee.txt file ``` ```java Deserializing Employee... First Name of Employee: Vivekanand Last Name of Employee: Gautam ``` 现在让我们尝试从`Employee.java`文件中删除“`serialVersionUID`”变量,然后再次运行“`SerializationClass.java`”文件。 它将再次创建带有对象状态的“`employee.txt`”文件。 现在让我们在`Employee`类中假设字符串地址中添加一个新变量。 `Employee.java` ```java package com.jbt; import java.io.Serializable; public class Employee implements Serializable { public String firstName; public String lastName; public String Address; //Variable is commented // private static final long serialVersionUID = 5462223600l; } ``` 现在运行“`DeserializationClass.java`”并查看输出。 ```java java.io.InvalidClassException: com.jbt.Employee; local class incompatible: stream classdesc serialVersionUID = 5462223600, local class serialVersionUID = -3607530122250644586 at java.io.ObjectStreamClass.initNonProxy(Unknown Source) at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source) at java.io.ObjectInputStream.readClassDesc(Unknown Source) at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) at java.io.ObjectInputStream.readObject0(Unknown Source) at java.io.ObjectInputStream.readObject(Unknown Source) at com.jbt.DeserializationClass.main(DeserializationClass.java:11) ``` 它将引发不兼容的异常。 因为给定的类`Employee.java`在序列化和反序列化过程之间进行了更改。 因此,系统无法识别它仍然是同一类。 为了使我们的系统了解到它是同一类,您必须在一个类中使用`serialVersionUID`变量。 您可以尝试执行上述步骤,但保持`serialVersionUID`不变,并查看输出。 反序列化过程将正常进行。 ### 项目要点 * 在可序列化类中定义`serialVersionUID`字段不是必需的。 * 如果可序列化的类具有显式的`serialVersionUID`,则此字段的类型应为`long`,并且必须是静态且最终的。 * 如果没有明确定义的`serialVersionUID`字段,则序列化运行时将计算该类的默认值。 该值可以根据编译器的实现而变化。 因此,建议定义`serialVersionUID`。 * 建议对`serialVersionUID`使用私有访问修饰符。 * 不同的类可以具有相同的`serialVersionUID`。 * 数组类无法声明显式的`serialVersionUID`,因此它们始终具有默认的计算值,但是对于数组类,无需匹配`serialVersionUID`值。 * 如果已加载的接收器类的`serialVersionUID`与相应的发送器类之间存在差异,则将引发`InvalidClassException`。 * 如果要禁止序列化同一类旧版本的新类,则应对同一类的不同版本使用不同的`serialVersionUID`。 ## `@SuppressWarnings("serial")` 如果您没有在应该序列化的类中提供`serialVersionId`,则编译器将给出有关该序列的警告消息。 如果要覆盖此警告,则可以使用给定的注解。 使用后,编译器将不再报错缺少的`serialVersionUID`。