我有以下代码尝试序列化/反序列化Throwable
public void test() throws IOException, ClassNotFoundException {
IllegalStateException exception = new IllegalStateException("Oooops!");
ByteBuffer seralized = serialize(exception);
String asString = new String(seralized.array(), Charset.forName("UTF-8"));
Throwable deserialized = deserialize(seralized);
// false
System.out.println(exception.equals(deserialized));
// true
System.out.println(exception.toString().equals(deserialized.toString()));
seralized = serialize(deserialized);
String toCompare = new String(seralized.array(), Charset.forName("UTF-8"));
// true
System.out.println(asString.equals(toCompare));
}
private Throwable deserialize(ByteBuffer seralized) throws IOException, ClassNotFoundException {
return (Throwable) new ObjectInputStream(new GZIPInputStream(
new ByteArrayInputStream(seralized.array()))).readObject();
}
private ByteBuffer serialize(Throwable exception) throws IOException {
ByteArrayOutputStream causeBytesOut = new ByteArrayOutputStream();
ObjectOutputStream causeOut = new ObjectOutputStream(
new GZIPOutputStream(causeBytesOut));
causeOut.writeObject(exception);
causeOut.close();
return ByteBuffer.wrap(causeBytesOut.toByteArray());
}
解释代码:我正在测试我的序列化/反序列化是否兼容。
第一个打印输出(false)告诉我,反序列化后得到的东西与我序列化的不同。
第二个印刷品(true)告诉对象“有点”相似。
我试图挖掘每个对象以查看有什么区别,所以我再次序列化它并查看字节缓冲区的内容。根据最后一次打印(true)看起来是一样的。
为什么初始对象和序列化/反序列化的对象虽然看起来不一样但有所不同?
答案 0 :(得分:1)
请查看以下对您所观察结果的解释。
在toString
类型的对象上调用IllegalStateException
将只返回完全限定的类名。这来自Throwable#toString()
。因此,对于两个对象都是相同的,equals
的结果将是真的
java.lang.IllegalStateException
IllegalStateException
或其父母不会覆盖equals
方法。因此,只会等同于自己。由于您的反序列化将创建一个新对象,因此您的对象在引用中不相等,因此equals
将返回false(根据Object#equals
)。
您正在使用以下表达式完全相同地创建asString
和toCompare
,因为这两个具有相同内容的不同字符串对象将等同,您的第3个表达式为真。 / p>
new String(seralized.array(), Charset.forName("UTF-8"));
如果您需要在使用原始对象调用equals()
时使反序列化对象返回true,则可以继承IllegalStateException
并覆盖equals
方法(此处toString
情况下)。
答案 1 :(得分:1)
IllegalStateException
不会覆盖Object.equals()
,因此它会通过==
运算符使用对象标识。因此,对于不同的实例,它将始终返回false。
您的测试无效。