首页 > 解决方案 > Java在反序列化时如何处理泛型类的对象?

问题描述

这是一个非常简单的泛型类:

import java.io.Serializable;

public class GenericDemoObject<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    T date;

    @Override
    public String toString() {
        return date.getClass().getName() + ':' + date.toString();
    }
}

然后我创建了一个GenericDemoObjectT 类型为的实例org.joda.time.LocalDate,并将其序列化到磁盘。然后我尝试使用以下代码对其进行反序列化:

private static Object deserialize(String fileName) throws IOException, ClassNotFoundException {
    try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName))) {
        return in.readObject();
    }
}

// LocalDate is java.time.LocalDate
GenericDemoObject<LocalDate> obj = (GenericDemoObject<LocalDate>) deserialize("GenericDemoObject.ser");

我不明白反序列化是如何工作的。为什么它不抛出 ClassCastException?

编辑:

更准确地说,我的意思obj是 GenericDemoObject 类型的引用,但是反序列化对象的日期字段是 org.joda.time.LocalDate 类型。该任务如何工作?

标签: javagenericsserializationdeserialization

解决方案


在测试了您在问题中发布的案例后,我确认您不会像您一样仅通过转换泛型来获得异常,真正的转换永远不会发生,直到您访问该字段date,请检查以下代码: public class Main {

    public static void main(String[] args) {
        org.joda.time.LocalDate date = org.joda.time.LocalDate.now();
        GenericDemoObject<org.joda.time.LocalDate> gdo = new GenericDemoObject<>();
        gdo.date = date;
        try {
            serialize("GenericDemoObject.ser", gdo);
        } catch (IOException | ClassNotFoundException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            GenericDemoObject<java.time.LocalDate> obj1 = (GenericDemoObject<java.time.LocalDate>) deserialize("GenericDemoObject.ser");//no exception
            GenericDemoObject<String> obj2 = (GenericDemoObject<String>) deserialize("GenericDemoObject.ser");//no exception
            LocalDate date1 = obj1.date;//The exception is thrown here
            String date2 = obj2.date;//The exception is thrown here

        } catch (ClassNotFoundException | IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private static Object deserialize(String fileName) throws IOException, ClassNotFoundException {
        try (ObjectInputStream in = new ObjectInputStream(new FileInputStream(fileName))) {
            return in.readObject();
        }
    }

    private static void serialize(String fileName, Object object) throws IOException, ClassNotFoundException {
        try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(fileName))) {
            out.writeObject(object);
        }
    }
}

class GenericDemoObject<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    T date;

    @Override
    public String toString() {
        return date.getClass().getName() + ':' + date.toString();
    }
}

我希望这回答了你的问题。

注意: 再次阅读评论,我认为Antoniossss确实回答了但并没有真正将其发布为答案。


推荐阅读