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