Как Java обрабатывает объект универсального класса при десериализации? - PullRequest
0 голосов
/ 29 сентября 2018

Вот очень простой универсальный класс:

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();
    }
}

Затем я создал экземпляр GenericDemoObject с типом T, равным 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.Как это назначение может работать?

1 Ответ

0 голосов
/ 29 сентября 2018

После тестирования случая, который вы разместили в своем вопросе, я подтверждаю, что вы не получите исключение, просто приведя обобщенное значение, как вы это сделали, настоящее приведение никогда не произойдет, пока вы не получите доступ к полю 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 действительно ответил, нона самом деле не опубликовал это как ответ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...