通过序列化复制多维数组

时间:2013-02-21 11:22:04

标签: java multidimensional-array deep-copy

我打算通过序列化复制一个三维数组,使用以下类:

public class Serializer {

    public byte[] serialize(Object obj) throws IOException {
        ByteArrayOutputStream b = new ByteArrayOutputStream();
        ObjectOutputStream o = new ObjectOutputStream(b);
        o.writeObject(obj);
        return b.toByteArray();
    }

    public Object deserialize(byte[] bytes) throws IOException,
            ClassNotFoundException {
        ByteArrayInputStream b = new ByteArrayInputStream(bytes);
        ObjectInputStream o = new ObjectInputStream(b);
        return o.readObject();
    }
}

然后,在我的主要代码中,我写了这个:

int array[][][] = new int[param][][];
Serializer s = new Serializer();
byte [] b = s.serialize(array);
Object arrayCopy = s.deserialize(b);

但是,我在最后一行收到错误消息:“未处理的异常类型ClassNotFoundException”

另外,我不知道如何将Object arrayCopy转换为int [param] [] [],这是我的最终目标。我怎么能这样做?

由于

1 个答案:

答案 0 :(得分:1)

  

但是,我在最后一行收到错误消息:“未处理   异常类型ClassNotFoundException“

您的deserialize方法抛出两个已检查的异常(IOException,ClassNotFoundException),这些异常必须在使用try-catch块调用代码时处理。

  

另外,我不知道如何将Object arrayCopy转换为   int [param] [] [],这是我的最终目标

通过在括号中添加所需类型(int [] [] [])的表达式的RHS来强制转换对象。请注意,在您的情况下,这是 unsafe 强制转换,因为您实际上不知道从deserialize方法返回的对象类型。

结合异常处理和强制转换,您的主要代码应如下所示:

try {
    int array[][][] = new int[param][][];
    Serializer s = new Serializer();
    byte [] b = s.serialize(array);
    Object arrayCopy = (int[][][]) s.deserialize(b);
} catch(IOException ioe) {
    // ... handle this
} catch(ClassNotFoundException cnfe) {
    // ... handle this
}

安全(呃)施法

如果您想避免不安全的转换,可以使用泛型来指示deserialize方法的预期返回类型。您还需要在方法本身中进行验证,即反序列化的对象实际上是所需的类类型。像这样:

public class Serializer {

    public <T> byte[] serialize(T obj) throws IOException {
        ByteArrayOutputStream b = new ByteArrayOutputStream();
        ObjectOutputStream o = new ObjectOutputStream(b);
        o.writeObject(obj);
        return b.toByteArray();
    }

    public <T> T deserialize(Class<T> clazz, byte[] bytes) throws IOException,
            ClassNotFoundException {
        ByteArrayInputStream b = new ByteArrayInputStream(bytes);
        ObjectInputStream o = new ObjectInputStream(b);
        final Object raw = o.readObject();
        if (raw.getClass().isAssignableFrom(clazz))
            return clazz.cast(raw);
        else
            throw new IllegalArgumentException(
                    "Byte data does not represent a class of type " + clazz);
    }
}

请注意deserialize方法的更改是:

  • 添加(方法级别)通用参数T
  • 添加一个表示要返回的预期类型的​​附加参数(Class<T>
  • 在方法中添加验证以确认反序列化对象实际上是所需类的实例
  • 如果反序列化对象 实际上是所需类的实例
  • ,则添加非法参数例外

如果您使用这些修改,请在主代码中处理IllegalArgumentException