我将应用程序中的字段保存为哈希集
@DatabaseField(dataType = DataType.SERIALIZABLE)
private HashSet<String> allUsers;
某些设备偶尔会出现错误,即该字段使用错误大小的字节进行序列化,因此无法反序列化。带有虚拟数据的错误消息示例:
java.sql.SQLException: Could not read serialized object from byte array: [-84, -19, 0, 5, 115, 114, 0, 17, 106, 97, 118, 97, 46, 117, 116, 105, 108, 46, 72, 97, 115, 104, 83, 101, 116, -70, 68, -123, -107, -106, -72, -73, 52, 3, 0, 0, 120, 112, 119, 12, 0, 0, 0, 16, 63, 64, 0, 0, 0, 0, 0, [this is the problem byte] 3, 116, 0, 4, 115, 111, 109, 101, 116, 0, 4, 100, 97, 116, 97, 120]
如果我更正大小字节以创建一个新数组,如下所示:
[-84, -19, 0, 5, 115, 114, 0, 17, 106, 97, 118, 97, 46, 117, 116, 105, 108, 46, 72, 97, 115, 104, 83, 101, 116, -70, 68, -123, -107, -106, -72, -73, 52, 3, 0, 0, 120, 112, 119, 12, 0, 0, 0, 16, 63, 64, 0, 0, 0, 0, 0, [correct size is 2] 2, 116, 0, 4, 115, 111, 109, 101, 116, 0, 4, 100, 97, 116, 97, 120]
然后我可以反序列化数组以找到包含两个字符串的 HashSet。
我想知道 HashSet 以这种方式被序列化为错误大小的字节的可能原因。我无法确定重现此问题的步骤,但它已在多个设备上发生。然而,运行该应用程序的绝大多数设备都没有这个问题。
我尝试通过序列化 HashSet,然后反序列化它,添加和删除对象,然后再次序列化来重现该问题。但我无法重现该问题。我想知道 Java 中的 HashSet 是否存在像这样错误序列化的已知原因。
某些设备偶尔会出现错误,即该字段使用错误大小的字节进行序列化,因此无法反序列化。
我最好的猜测是某些东西正在修改另一个线程中的
HashSet
。 ORMLite 所做的就是将数据序列化到缓冲区中,然后将其存储为字节包。查看 SerializedType.sqlArgToJava(...) 中相当简单的代码。它基本上是在做:
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
objOutStream = new ObjectOutputStream(outStream);
objOutStream.writeObject(obj);
objOutStream.close();
return outStream.toByteArray();
正如您所提到的,序列化的
HashSet
表示其大小为 3,但集合中仅存储 2 个字符串。我可以看到当一个元素添加到 HashSet 并且大小字段已更新但底层节点数组未更新时会发生这种情况。怀疑序列化流的问题不在字符串或其他数据的中间。