0

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

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][][],这是我的最终目标。我怎样才能做到这一点?

谢谢

4

1 回答 1

1

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

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

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

您可以通过在表达式的 RHS 前面加上所需类型 (int[][][]) 来转换对象。请注意,在您的情况下,这是一个不安全的强制转换,因为您真的不知道从该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.

于 2013-02-21T12:10:41.653 回答