我打算使用以下类通过序列化复制三维数组:
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〕〔〕〔〕,这是我的最终目标。我该怎么做?
感谢
然而,我确实在最后一行收到了一条错误消息:"未处理异常类型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
。