【问题标题】:Cannot Serialize/Deserialize ArrayList无法序列化/反序列化 ArrayList
【发布时间】:2009-03-24 17:46:12
【问题描述】:

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

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&lt;HairBirt&gt;) obj_in.readObject();

我不知道我做错了什么。能给个小费吗?

更新:

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

HairBirt[] list = new HairBirt[x];

而不是

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

感谢大家的帮助。

【问题讨论】:

    标签: java serialization


    【解决方案1】:

    不要使用ByteArrayOutputStream.toString() - 而是使用toByteArray() 并对二进制数据进行base64 编码以将其转换为字符串而不会丢失信息。

    我强烈怀疑这是主要问题 - 您在序列化后丢失了数据。您可能还应该关闭或至少刷新ObjectOutputStream。我不知道在这种情况下这是否真的有任何作用,但这似乎是个好主意。

    我不相信 Java 中直接有任何 base64 支持(无论如何是在公共类中),但是您可以使用各种 3rd 方库,例如 the one in the Apache Commons Codec library

    【讨论】:

    • 是的,这就是问题所在,但我确实需要在这一步中使用字符串...这不是真正的问题,它是它的简化。
    • 你所说的“在那一步”是什么意思?如果您希望能够对其进行反序列化,您将必须以无损方式将 BAOS 转换为字符串。是否使用 base64 是另一回事,但我认为这是一种很好的方法。
    • @sakana:base64 是一种字符串格式,字符集有限。
    • 你所说的“在那一步”是什么意思?我的意思是我真的需要在编码和解码代码之间使用一个字符串。这是我唯一可以使用的参数类型。
    • 没关系 - 这就是为什么你使用 base64 从 byte[] 转换为 String 而不会丢失信息的原因。
    【解决方案2】:

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

    您是否有特定原因需要执行通过字符串进行序列化的额外步骤?通常,您只需通过 ObjectOutputStream 反序列化。

    【讨论】:

    • 声明一个 serialVersionUID 在这里没有帮助。
    猜你喜欢
    • 1970-01-01
    • 2015-05-29
    • 2019-03-17
    • 2013-05-07
    • 2011-07-19
    • 2011-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多