XStream在Android上抛出异常“no-args构造函数”

时间:2011-09-08 02:54:17

标签: java android xml-serialization xstream

我正在尝试使用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对象可以正常工作。我怎样才能摆脱这个错误?

1 个答案:

答案 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而言,你就不走运了。