无法序列化/反序列化ArrayList

5

我正在尝试对一个包含对象的数组列表进行序列化和反序列化:

HairBirt param = new HairBirt();
param.setName("name");
param.setValue(2.3f);

HairBirt param2 = new HairBirt();
param2.setName("name2");
param2.setValue(2.4f);

ArrayList<HairBirt> list = new ArrayList<HairBirt>();

list.add(param);

list.add(param2);

ByteArrayOutputStream bos = null;
try {
    bos = new ByteArrayOutputStream();
    ObjectOutputStream obj_out = new ObjectOutputStream(bos);
    obj_out.writeObject(list);
} catch (IOException e) {
    e.printStackTrace();
}

String encoded = bos.toString();
try {
    encoded = URLEncoder.encode(encoded, "UTF-8");
} catch (UnsupportedEncodingException e1) {
    e1.printStackTrace();
}
System.out.print("The serialized output is: " + encoded);   

//DECODE

ArrayList<HairBirt> paramDecoded;

String myParam = null;
try {
    myParam = URLDecoder.decode(encoded, "UTF-8");
} catch (UnsupportedEncodingException e1) {
    e1.printStackTrace();
}
System.out.println("Got parameters");
ByteArrayInputStream bis = new ByteArrayInputStream(myParam.getBytes());

try {
    ObjectInputStream obj_in = new ObjectInputStream(bis);

    paramDecoded = (ArrayList<HairBirt>) obj_in.readObject();
} catch (IOException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

HairList对象也是可序列化的对象。

执行此代码时返回以下错误:

java.io.InvalidClassException: java.util.ArrayList; local class incompatible: stream classdesc serialVersionUID = 8664875232659988799, local class serialVersionUID = 8683452581122892189

paramDecoded = (ArrayList<HairBirt>) obj_in.readObject();行。

我不知道我做错了什么。你能给个提示吗?

更新:

已解决: 只需使用HairBirt的本机数组而不是ArrayList即可:

HairBirt[] list = new HairBirt[x];

替代

ArrayList<HairBirt> list = new ArrayList<HairBirt>();

谢谢大家的帮助。
2个回答

9
不要使用ByteArrayOutputStream.toString()方法 - 相反,使用toByteArray()方法并对二进制数据进行base64编码,以将其转换为字符串而不丢失信息。
我强烈怀疑这是主要问题 - 在序列化后你正在丢失数据。您应该关闭或至少刷新ObjectOutputStream。我不知道在这种情况下它是否实际起作用,但这似乎是个好主意。
我不认为Java中有任何直接支持base64的类(至少是公共类),但可以使用各种第三方库,例如Apache Commons Codec库中的库

没错,那就是问题所在,但我确实需要在那个移动上使用字符串... 这并不是真正的问题,只是它的简化版。 - sakana
“on that move”是什么意思?如果您想要反序列化,您必须以无损的方式将BAOS转换为字符串。是否使用base64并不重要,但我认为这是一个很好的方法。 - Jon Skeet
@sakana:base64是一种具有有限字符集的字符串格式。 - Powerlord
“在那个移动上”是什么意思? 我指的是我真的需要在编码和解码代码之间使用一个字符串。这是我能够使用的唯一参数类型。 - sakana
没问题 - 这就是为什么你使用base64将byte[]转换为String而不会丢失信息的原因。 - Jon Skeet

0

你尝试过通过在自定义类中声明自己的serialVersionUID来覆盖此行为吗?

你有特定的原因要通过字符串进行序列化的额外步骤吗?通常情况下,你只需要通过ObjectOutputStream进行反序列化。


在这里声明serialVersionUID是没有帮助的。 - Michael Myers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接