Why serialVersionUID Is Required??
serialVersionUID is used to identify the class during deserialization process.if you don't mention serialVersionUID in your class then by default JVM will generate it .
JVM generated serialVersionUID will be a 64 bit hash value of class name ,method and fields.But there is a problem in not declaring serialVersionUID manually.
Let me explain it with the example ,
This is my class which i want to serialize
public class Employee implements Serializable {
/**
*
*/
public int getEmpId() {
return empId;
}
public void setEmpId(int empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
private int empId;
transient private String empName;
}
In the above code i didn't declare serialVersionUID.
Below code used to serialize the Employee object
public class SerializationTest {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
try {
Employee emp = new Employee();
emp.setEmpId(1);
emp.setEmpName("saradha");
FileOutputStream fout = new FileOutputStream("test.text");
ObjectOutputStream out= new ObjectOutputStream(fout);
out.writeObject(emp);
fout.close();
out.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
try {
Employee emp = new Employee();
emp.setEmpId(1);
emp.setEmpName("saradha");
FileOutputStream fout = new FileOutputStream("test.text");
ObjectOutputStream out= new ObjectOutputStream(fout);
out.writeObject(emp);
fout.close();
out.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
out put file will be generated with serialized Employee object .
now i am changing the empId field name to empId1,then i am going to deserialize it using the following class
public class deserializationTest {
/**
* @param args
* @throws IOException
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
// TODO Auto-generated method stub
FileInputStream fin = null;
try {
fin = new FileInputStream("test.text");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ObjectInputStream out= new ObjectInputStream(fin);
Employee e=(Employee)out.readObject();
fin.close();
out.close();
System.out.println("id-"+e.getEmpId());
System.out.println("name-"+e.getEmpName());
}
}
/**
* @param args
* @throws IOException
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
// TODO Auto-generated method stub
FileInputStream fin = null;
try {
fin = new FileInputStream("test.text");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ObjectInputStream out= new ObjectInputStream(fin);
Employee e=(Employee)out.readObject();
fin.close();
out.close();
System.out.println("id-"+e.getEmpId());
System.out.println("name-"+e.getEmpName());
}
}
Now the following exception will be thrown in console:
Exception in thread "main" java.io.InvalidClassException: com.saradha.serialize.test.Employee; local class incompatible: stream classdesc serialVersionUID = 4984626804719984326, local class serialVersionUID = -4174571632522634906
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:562)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1582)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at com.saradha.serialize.test.deserializationTest.main(deserializationTest.java:26)
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:562)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1582)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
at com.saradha.serialize.test.deserializationTest.main(deserializationTest.java:26)
This is because after changing the field name in Employee class it's serialVersionUID will get changed . so it is a good practice to declare serialVersionUID always.
where are you changing the field name here?
ReplyDelete