【问题标题】:copying a multidimensional array via serialization通过序列化复制多维数组
【发布时间】:2013-02-21 11:22:03
【问题描述】:

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

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][][],这是我的最终目标。我该怎么做?

谢谢

【问题讨论】:

  • 整个序列化程序类实际上并没有做什么,你想要什么。 ObjectStream 读取 Java 对象(例如,字符串或列表)而不是字节数组。它只从输入流(字节数组)中读取。

标签: java multidimensional-array deep-copy


【解决方案1】:

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

您的 deserialize 方法会引发两个检查异常(IOException、ClassNotFoundException),必须在使用 try-catch 块调用代码时对其进行处理。

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

您可以通过在表达式的 RHS 前面加上所需的类型 (int[][][]) 来转换对象。请注意,在您的情况下,这是一个 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&lt;T&gt;),表示要返回的预期类型
  • 在方法中添加验证以确认反序列化的对象实际上是所需类的实例
  • 添加非法参数异常,在反序列化对象不是实际上是所需类的实例的情况下

如果您使用这些修改,在您的主代码中您还应该处理IllegalArgumentException

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-05
    • 1970-01-01
    • 1970-01-01
    • 2010-09-18
    • 2012-06-10
    • 1970-01-01
    相关资源
    最近更新 更多