为何在同一文件序列化反序列化Java对象时静态成员显示序列化值?
问题
根据Java官方文档,静态成员无法被序列化,但在同一文件中执行对象的序列化与反序列化操作后,打印出的静态成员Data显示为序列化时的赋值500,而非初始值10;若注释序列化部分则结果正常。
相关代码
import java.io.*; class Student_serial implements Serializable { int rollNo; String name; String dept; float avg; public static int Data = 10; public transient int t = 100; public Student_serial() { } public Student_serial(int r, String n, String d, float a) { rollNo = r; name = n; dept = d; avg = a; Data = 500; t = 500; } public String toString() { return "\nStudent Details\n"+ "\nRoll "+rollNo+ "\nName "+name+ "\nAverage "+avg+ "\nDept "+dept+ "\nData "+Data+ "\nTransient "+t+"\n"; } } public class Object_Stream_And_Serialisation { public static void main(String[] args) throws Exception { //Serialisation of Object FileOutputStream fos = new FileOutputStream("C:/users/kbb91/Desktop/A-B-Java/Studetn3.txt"); ObjectOutputStream oos = new ObjectOutputStream(fos); Student_serial s = new Student_serial(7, "KB", "Army", 9.5f); oos.writeObject(s); //Deserialization of Object FileInputStream fis = new FileInputStream("C:/users/kbb91/Desktop/A-B-Java/Studetn3.txt"); ObjectInputStream ois = new ObjectInputStream(fis); Student_serial s1; s1 = (Student_serial) ois.readObject(); System.out.println(s1); } }
实际输出
Student Details Roll 7 Name KB Average 9.5 Dept Army Data 500 Transient 0
期望输出
Student Details Roll 7 Name KB Average 9.5 Dept Army Data 10 Transient 0
原因分析
这是因为静态成员属于类而非对象,Java序列化机制只会处理对象的实例数据,不会序列化静态成员。你看到的Data=500并不是从序列化文件中读取的,而是因为在当前程序运行过程中,创建s对象时通过构造函数把Student_serial类的静态Data值改成了500——这个值存储在类的内存空间中,整个程序运行期间都会生效。
当你反序列化得到s1对象时,程序并没有从文件里读取静态成员的值,而是直接使用当前类中已经存在的Data值(也就是之前构造函数修改后的500)。
如果注释掉序列化部分,程序不会创建s对象,构造函数不会被调用,静态Data就保持初始值10,所以输出符合预期。
你可以做个验证:在反序列化代码前手动执行Student_serial.Data = 10;,会发现反序列化后的对象打印出来的Data就是10,完全和序列化文件无关。
内容的提问来源于stack exchange,提问作者Karan Badhwar
相关产品推荐
相关产品推荐

