Child Class 可序列化为文件,但文件不可反序列化
Child Class is Serializable into a file, but the file is not Deserializable
我们有一个名为“Vehicle”的超级 class,它实现了标记接口 Serializable。
然后我们有一个子 class 称为“Car”,它继承了“Vehicle”,因此子 class“Car”也实现了 Serializable 标记接口,因为它是父“Vehicle”。
现在我们可以将车辆的任何实例序列化为文件,没有任何问题。
但是当我们尝试将该文件反序列化为“Car”类型的对象时,程序会抛出异常。
我解决这个问题的方法是在“汽车”中手动实现可序列化标记接口class。
为什么会这样?从我今天阅读的关于连载的所有内容来看,似乎没有人涵盖这个问题。
我得出的结论是:当“Car”class继承“Vehicle”class时,它也继承了“Vehicle”中实现的接口,因此“Car” " 对象是可序列化的,但是一旦我们将“Car”对象的一个实例序列化为一个文件(例如:“car1.ser”),“car1.ser”文件就会写入一个对象,其中它的所有修饰符、属性、方法等。
但是不知何故,写入“car1.ser”文件的“Car”类型的对象并没有从它的父级继承“Serializable”标记。这是什么原因,我不是很清楚。
什么异常? (请考虑将其添加到 post,因为它看起来像是一个“重要细节”)
抱歉,不能 re-produce/comprehend:
package com.example.serial;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class SerialTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Car car = new Car();
car.manufacturer = "Toyota";
car.model = "Land Cruiser";
// tmp memory:
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
// write object:
ObjectOutputStream oos = new ObjectOutputStream(outStream);
oos.writeObject(car);
// input stream of "tmp memory":
ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray());
// read object:
ObjectInputStream ois = new ObjectInputStream(inStream);
Car c2 = (Car) ois.readObject();
// print/verify:
System.out.println(c2);
}
}
class Vehicle implements Serializable {
private static final long serialVersionUID = 0L;
String manufacturer;
}
class Car extends Vehicle {
String model;
}
打印:
com.example.serial.Car@1ed6993a
我们还可以:
Vehicle car = new Car();
// ... same code, but without "model"
但不是:
Vehicle car = new Vehicle();
...
..这将导致:
java.lang.ClassCastException: class com.example.serial.Vehicle cannot be cast to class com.example.serial.Car
在这一行:
Car c2 = (Car) ois.readObject();
参考:https://docs.oracle.com/en/java/javase/17/docs/specs/serialization/serial-arch.html
我们有一个名为“Vehicle”的超级 class,它实现了标记接口 Serializable。 然后我们有一个子 class 称为“Car”,它继承了“Vehicle”,因此子 class“Car”也实现了 Serializable 标记接口,因为它是父“Vehicle”。
现在我们可以将车辆的任何实例序列化为文件,没有任何问题。 但是当我们尝试将该文件反序列化为“Car”类型的对象时,程序会抛出异常。
我解决这个问题的方法是在“汽车”中手动实现可序列化标记接口class。
为什么会这样?从我今天阅读的关于连载的所有内容来看,似乎没有人涵盖这个问题。
我得出的结论是:当“Car”class继承“Vehicle”class时,它也继承了“Vehicle”中实现的接口,因此“Car” " 对象是可序列化的,但是一旦我们将“Car”对象的一个实例序列化为一个文件(例如:“car1.ser”),“car1.ser”文件就会写入一个对象,其中它的所有修饰符、属性、方法等。 但是不知何故,写入“car1.ser”文件的“Car”类型的对象并没有从它的父级继承“Serializable”标记。这是什么原因,我不是很清楚。
什么异常? (请考虑将其添加到 post,因为它看起来像是一个“重要细节”)
抱歉,不能 re-produce/comprehend:
package com.example.serial;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class SerialTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Car car = new Car();
car.manufacturer = "Toyota";
car.model = "Land Cruiser";
// tmp memory:
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
// write object:
ObjectOutputStream oos = new ObjectOutputStream(outStream);
oos.writeObject(car);
// input stream of "tmp memory":
ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray());
// read object:
ObjectInputStream ois = new ObjectInputStream(inStream);
Car c2 = (Car) ois.readObject();
// print/verify:
System.out.println(c2);
}
}
class Vehicle implements Serializable {
private static final long serialVersionUID = 0L;
String manufacturer;
}
class Car extends Vehicle {
String model;
}
打印:
com.example.serial.Car@1ed6993a
我们还可以:
Vehicle car = new Car();
// ... same code, but without "model"
但不是:
Vehicle car = new Vehicle();
...
..这将导致:
java.lang.ClassCastException: class com.example.serial.Vehicle cannot be cast to class com.example.serial.Car
在这一行:
Car c2 = (Car) ois.readObject();
参考:https://docs.oracle.com/en/java/javase/17/docs/specs/serialization/serial-arch.html