我正在尝试使用XStream来(在)Android应用中序列化我自己的一些类的HashMap。例如,其中一个类是Word,它具有以下变量:
private String word;
private boolean capitalizable;
private int useCount;
private HashMap<Character,Integer> endPunctuation;
private HashSet<String> nextWritables;
我已经将整个设置工作在一个标准的Java应用程序中,我只是试图将它全部包装在一个Android UI中(工作正常)。序列化在Android中运行良好。我遇到的问题是当我反序列化时,我收到以下错误:
com.thoughtworks.xstream.converters.ConversionException: Cannot construct chatai.Word as it does not have a no-args constructor : Cannot construct chatai.Word as it does not have a no-args constructor
---- Debugging information ----
message : Cannot construct chatai.Word as it does not have a no-args constructor
cause-exception : com.thoughtworks.xstream.converters.reflection.ObjectAccessException
cause-message : Cannot construct chatai.Word as it does not have a no-args constructor
class : java.util.HashMap
required-type : chatai.Word
path : /map/entry/chatai.Word
line number : 1
-------------------------------
如果我在桌面应用程序上使用1.4.1以外的任何版本的XStream,则会出现此错误。我总是在我的android应用程序上得到错误,无论是XStream的版本。我确信桌面设备有问题,因为它在Java 7上运行。我不确定android。它与反射有关,因为在添加xstream-1.4.1.jar时会出现此警告:
[2011-09-07 21:06:52 - DroidBot] Dx warning: Ignoring InnerClasses attribute for an anonymous inner class
(com.thoughtworks.xstream.XStream$2) that doesn't come with an
associated EnclosingMethod attribute. This class was probably produced by a
compiler that did not target the modern .class file format. The recommended
solution is to recompile the class from source, using an up-to-date compiler
and without specifying any "-target" type options. The consequence of ignoring
this warning is that reflective operations on this class will incorrectly
indicate that it is *not* an inner class.
快速测试显示,在Android中序列化和反序列化String对象可以正常工作。我怎样才能摆脱这个错误?
答案 0 :(得分:2)
是的,这个问题很老,但对于好奇的互联网研究人员来说:
反序列化要求xstream构造一个对象,并将其所有成员字段设置为xml中指定的值。如果您尝试反序列化的对象没有no-arg构造函数,那么xstream需要来自VM的帮助才能在对象实例化和初始化的正常过程之外构建对象。此帮助仅在某些VM中可用;在Android设备上运行时,它在Dalvik VM下无法使用。
如果检查用于反序列化xml的提供程序,您会发现在桌面上提供程序可能是Sun14ReflectionProvider,它使用特殊的VM支持来构造对象而不调用它们的构造函数。在Android下,提供程序将是PureJavaReflectionProvider,它不能反序列化缺少no-arg构造函数的对象。
XStream xstream = new XStream();
ReflectionProvider rp = xstream.getReflectionProvider();
if(null != rp)
{
System.out.println("Provider class: " + rp.getClass().getName());
if(rp instanceof Sun14ReflectionProvider)
System.out.println("Using Sun14ReflectionProvider");
else if(rp instanceof PureJavaReflectionProvider)
System.out.println("Using PureJavaReflectionProvider");
}
总结:在Android环境中运行XStream时,不能反序列化缺少无参数构造函数的对象。如果您可以控制对象,则将其重构为具有无参数构造函数。如果你无法控制对象,那么就XStream而言,你就不走运了。