Java序列化中的SerialVersionUID
SerialVersionUID用于确保在Deserialization期间加载相同的类(在序列化期间使用).SerialVersionUID用于对象的版本控制。
如果我们已经使用序列化,那么我们可能已经看到SerialVersionUID,因为每当我们实现序列化接口时,IDE会给我们发出警告。
SerialVersionUID语法:
根据Java文档
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
SerialVersionUID必须是静态和最终的。
我们可以将任何号码分配给它。
让我们看一个例子:在src-> org.igi.javapostsforlearning中创建employee.java.java
1.Employee.java.
package org.igi.javapostsforlearning; import java.io.Serializable; public class Employee implements Serializable{ private static final long serialVersionUID = 1L; int employeeId; String employeeName; String department; public int getEmployeeId() { return employeeId; } public void setEmployeeId(int employeeId) { this.employeeId = employeeId; } public String getEmployeeName() { return employeeName; } public void setEmployeeName(String employeeName) { this.employeeName = employeeName; } public String getDepartment() { return department; } public void setDepartment(String department) { this.department = department; } }
在src-> org.igi.javapostsforlearning中创建serializemain.java
2.SerializeMain.java.
package org.igi.javapostsforlearning; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; public class SerializeMain { /** * @author igi Mandliya */ public static void main(String[] args) { Employee emp = new Employee(); emp.setEmployeeId(101); emp.setEmployeeName("igi"); emp.setDepartment("CS"); try { FileOutputStream fileOut = new FileOutputStream("employee.ser"); ObjectOutputStream outStream = new ObjectOutputStream(fileOut); outStream.writeObject(emp); outStream.close(); fileOut.close(); }catch(IOException i) { i.printStackTrace(); } } }
在src-> org.igi.javapostsforlearning中创建deserializemain.java
3.deserializemain.java.
package org.igi.javapostsforlearning; import java.io.IOException; import java.io.ObjectInputStream; public class DeserializeMain { /** * @author igi Mandliya */ public static void main(String[] args) { Employee emp = null; try { FileInputStream fileIn =new FileInputStream("employee.ser"); 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("Deserialized Employee..."); System.out.println("Emp id: " + emp.getEmployeeId()); System.out.println("Name: " + emp.getEmployeeName()); System.out.println("Department: " + emp.getDepartment()); } }
4.运行:
首先运行serializemain.java然后deserializemain.java,我们将得到以下输出:
Deserialized Employee... Emp id: 101 Name: igi Department: CS
因此,当我们运行程序时,它已成功完成,员工已在磁盘上创建。
如果我们再次运行DeserializeMain.java,则会再次成功运行。
现在将变量序列的值更改为
private static final long serialVersionUID = 2L;
如果我们现在运行deserializemain.java,它会给我们遵循错误。
java.io.InvalidClassException: org.igi.javapostsforlearning.Employee; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2
所以这里在反序列化期间,我们得到了错误。
抱怨串行vvesionuid正在改变。
但它如何知道?
因为erialVersionUID是一个静态变量,我们知道"我们不能序列化静态变量"。
它是它存储序列号吗?
是的,存在异常。
erialVersionUID存在静态,它会在每次输出流时写入序列化。
ObjectInputStream读取它,如果它没有与当前版本的类中的值相同,那么它会投掷InvalidClassexception。
为什么需要serialversionuid?
实时,我们可能在文件中序列化了一个对象,并且在不同的JVM上几个月后序列化了它。
在序列化和解放类声明之间进行了更改。
所以维护版本系统和SerialVersionID是一个好主意完全相同的事情。
检查是否要为我们序列化的相同对象进行反序列化。