我正在探索Java序列化和反序列化,但想知道反序列化是如何工作的。
这是我的序列化和反序列化代码:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class Testing{
public static void main(String[] args){
Serial obj = new Serial();
Serial ObjNew = null;
try{
FileOutputStream fob= new FileOutputStream("file.src");
ObjectOutputStream oob= new ObjectOutputStream(fob);
oob.writeObject(obj);
oob.close();
}catch(Exception fnf){
fnf.printStackTrace(System.out);
}
try{
FileInputStream fis = new FileInputStream("file.src");
ObjectInputStream ois = new ObjectInputStream(fis);
ObjNew=(Serial)ois.readObject();
}
catch(IOException | ClassNotFoundException fnf){
fnf.printStackTrace(System.out);
}
System.out.println("OLD: "+obj);
System.out.println("NEW: "+ObjNew);
}
}
此处可序列化的类代码:
import java.io.Serializable;
public class Serial implements Serializable {
private final String ok="DONE";
@Override
public String toString(){
return ok;
}
}
上面的代码一切正常。 但是当我尝试使用此代码反序列化对象时。
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class Testing{
public static void main(String[] args){
Serial ObjNew = null;
try{
FileInputStream fis = new FileInputStream("file.src");
ObjectInputStream ois = new ObjectInputStream(fis);
ObjNew=(Serial)ois.readObject();
}
catch(IOException | ClassNotFoundException fnf){
fnf.printStackTrace(System.out);
}
System.out.println("NEW: "+ObjNew);
}
}
我刚刚更改了Serializable Class中String ok="Do";
的值,只是为了测试Deserialize输出。
但它只是打印Do
而不是存储在文件中的值DONE
。
为什么只打印Do
?
为什么它没有从文件中读取值?
任何帮助?
答案 0 :(得分:3)
可序列化的Java类的要求是它可以在其第一个非可序列化的超类中访问无参数构造函数。 Java序列化利用了这个无参数构造函数。这与声明它通过此构造函数创建新类并不完全相同,但是类的构造的某些方面是在类中设置字段之前执行的。其中一个方面是最终常量的设置,因为它们需要在类被认为是“构造”之前设置。
你有一个最后的领域。课堂建设后无法设置。有了这样的项目,该字段没有被序列化到磁盘上的文件中(至少我认为不是这样),即使它是从磁盘读取的,也无法重置该字段,因为该字段不会“final”关键字。如果您将其更改为非最终版,则应该会有不同的结果。
由于您实际上借用了一个类定义并使用该定义的快照填充它,因此您需要一个工具来确定定义何时漂移得太远而无法协调。这是serialVersionID
成员的主要目的。
答案 1 :(得分:1)
final
变量只能分配一次。
删除最终修饰符,然后重试。
答案 2 :(得分:0)
这取决于您的final
字段修饰符。
我有ObjectInputStream
的源代码,并找到了此代码
Object obj;
try {
obj = desc.isInstantiable() ? desc.newInstance() : null; // here instance created
} catch (Exception ex) {
throw (IOException) new InvalidClassException(
desc.forClass().getName(),
"unable to create instance").initCause(ex);
}
在您的实例创建值" DO" 应用于该字段后,由于字段为final
,因此无法再修改