如何将Joda-Time LocalDate数组反序列化为java.time LocalDate?

时间:2018-09-29 17:27:09

标签: java serialization jodatime java-time

自从最近迁移到Java 10以来,我们还考虑在代码库中用Joda-Time类替换java.time。最大的障碍是如何处理现有的序列化Java对象,这些对象具有Joda-Time数组(例如LocalDatePeriod)作为字段。

项目中使用的Joda-Time版本是自定义版本,即。我们可以完全控制它。我试图在Joda-Time readObject中提供LocalDate实现,以使其返回Java LocalDate。但是,如果LocalDates包含在一个数组中(从ArrayStoreException的{​​{1}}方法抛出readArray的数组中,这是行不通的,因为LocalDate的本地版本是Java版本)。

ObjectInputStream

我什至试图对// code taken from ObjectInputStream Object array = null; Class<?> cl, ccl = null; if ((cl = desc.forClass()) != null) { ccl = cl.getComponentType(); // ccl is java LocalDate.class array = Array.newInstance(ccl, len); } ...// intermediate code ignored Object[] oa = (Object[]) array; for (int i = 0; i < len; i++) { oa[i] = readObject0(false); // ArrayStoreException thrown here, readObject0 returns a joda LocalDate handles.markDependency(arrayHandle, passHandle); } 进行子类化,以使其解析为Java ObjectInputStream,以防它反序列化joda LocalDate。由于JVM检测到序列化的LocalDate与解析的序列号没有相同的serialVersionUID,因此它不起作用(由于Java LocalDate具有不同的UID,因此显然是正确的)。在突破的直截了当的想法中,我尝试通过反射和覆盖LocalDate.class的{​​{1}}使两者返回相同的UID。但是后来又发生了新的异常。使事情变得复杂的是,Java时间序列化是由Ser.class以readClassDescriptor的方式完成的,与joda time不同。而且ObjectInputStream对它们的处理方式不同。所以现在我被卡住了。

在对ObjectInputStream进行子类化之前,我想听更多的人关于您对此类问题的想法/经验,或者从技术上讲如何反序列化更改后的数组对象版本。顺便说一句,我非常怀疑我是否能够以正确的方式解决我所面临的问题,即能够读取现有的序列化对象。

示例代码:

ObjectInputStream

首先运行上面的代码以生成一个ser文件。然后,注释对方法Externalizable的调用,并用java LocalDate替换joda LocalDate。再次运行该代码,您将得到一个ClassCastException,它表示它正在尝试将org.joda.time.LocalDate转换为java.time.LocalDate。我们可以通过将ObjectInputStream子类化并重写readObject方法来返回java LocalDate来解决这个问题,以防反序列化joda。

import org.joda.time.LocalDate;

import java.io.Serializable;
import java.util.Arrays;

public class DemoObject implements Serializable {

    private static final long serialVersionUID = 1L;

    private LocalDate[] dates;

    public DemoObject(LocalDate[] dates) {
        this.dates = dates;
    }

    @Override
    public String toString() {
        return Arrays.asList(dates).toString();
    }
}

///////////////////////////////////////////////////////////////////

import org.joda.time.LocalDate;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Arrays;
import java.util.List;

public class SerializationDemo {

    public static void main(String[] args) throws Exception {
        LocalDate[] dates = new LocalDate[2];
        for (int i=0; i<dates.length; i++) {
            dates[i] = new LocalDate().minusDays(i);
        }

        DemoObject demoObject = new DemoObject(dates);
        serialize(demoObject);
        deserialize(getSerialFileName(demoObject));
    }

    private static void serialize(Object demoObject) throws IOException {
        try(ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(getSerialFileName(demoObject)))) {
            out.writeObject(demoObject);
        }
    }

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

但是,构造反序列化的数组对象时,将引发ArrayStoreException。

serialize(demoObject);

如何解决数组问题?

0 个答案:

没有答案