我正在观察XStream库中的奇怪行为,同时读取它生成的文件并在结果上使用Patter.compile
运行时,它会给出空指针异常 ,但如果我在调试模式下逐步运行 ,它会正常工作。
我把它缩小到Pattern.complie如果我只是将值读取到一个字符串变量它工作正常,如果我使用Pattern.complie(“。*”)和unmarshal方法它也可以正常工作
我使用Java 7和XStream 1.4.4
我认为这是由于reader.getAttribute(“key”)返回null但不是在调试时
知道为什么这么开心呢?
这就是我所拥有的:
我的班级
import java.util.regex.Pattern;
public class A {
private Pattern key;
ArrayList<A> subTree;
public A(HierarchicalStreamReader reader, UnmarshallingContext context){
this.key=Pattern.compile(reader.getAttribute("key"));
// String a = reader.getAttribute("key") - Works fine
// this.key=Pattern.compile(a) - Breaks
subTree=new ArrayList<A>();
reader.moveDown();
while(reader.hasMoreChildren()) {
subTree.add(new A(reader,context));
}
reader.moveUp();
}
}
XStream转换器类
public class AConverter implements Converter {
public boolean canConvert(Class clazz) {
return A.class.isAssignableFrom(clazz);
}
public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
}
public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
reader.moveDown();
A n = new A(reader,context);
reader.moveUp();
return n;
}
}
测试用例
public void testA() throws FileNotFoundException, IOException, ClassNotFoundException{
XStream xstream = new XStream();
xstream.alias("MessageFieldMappings", A.class);
xstream.registerConverter(new AConverter());
ObjectInputStream in = xstream.createObjectInputStream(new FileInputStream("test1.xml"));
A rootNode = (A) in.readObject();
in.close();
}
测试文件(test1.xml)
<object-stream>
<MessageFieldMappings>
<RootMapping>
<FieldMap key=".*">
<FieldMap key="A.*">
<FieldMap key="AB.*"/>
<FieldMap key="AC.*"/>
</FieldMap>
<FieldMap key="D.*"/>
</FieldMap>
</RootMapping>
</MessageFieldMappings>
</object-stream>
我得到的错误
com.thoughtworks.xstream.converters.ConversionException: null : null
---- Debugging information ----
cause-exception : java.lang.NullPointerException
cause-message : null
class : nz.orion.monkPraser.praser.fieldConverter.A
required-type : nz.orion.monkPraser.praser.fieldConverter.A
converter-type : nz.orion.monkPraser.praser.fieldConverter.AConverter
path : /MessageFieldMappings/RootMapping
line number : 3
version : null
-------------------------------
at com.thoughtworks.xstream.core.TreeUnmarshaller.convert(TreeUnmarshaller.java:79)
...
答案 0 :(得分:1)
线索在
path : /MessageFieldMappings/RootMapping
line number : 3
您已将MessageFieldMappings
别名加入了课程A
,因此当它看到MessageFieldMappings
时,它会调用转换器,moveDown
将转移到RootMapping
元素并尝试从中提取key
属性。它没有,因此是NPE。
转换器中需要额外的moveDown / Up级别:
reader.moveDown(); // RootMapping
reader.moveDown(); // First FieldMap
A n = new A(reader,context);
reader.moveUp();
reader.moveUp();
return n;