如果匹配的 Java 类使用绑定(bind)到抽象类的泛型类型,我遇到了使用 JAXB 解码 XML 文件的问题。
我已经提交了关于此行为的错误报告( java.net/jira ),但是我错过了一些东西或者有人有解决这个问题的想法?所以这是我的问题:
在下面的示例中,我需要任何类型的 Number 的边界,但 JAXB 尝试通过实例化为抽象的 Number 来解码它。 省略边界或将其更改为可实例化类型(如 Object)可以解决问题,但会削弱泛型。
以下示例显示了这一点,请参阅包含的注释。删除停用类型边界的注释,该程序将失败。
import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
public class JaxbTester {
/*
* AbstractContainer<T> -> works, but misses boundaries
* AbstractContainer<T extends Object> -> works, but boundaries are too large
* AbstractContainer<T extends Number> -> fails: "Exception in thread "main" javax.xml.bind.UnmarshalException: Unable to create an instance of java.lang.Number"
*/
static abstract class AbstractContainer<T /* extends Number */> {
@XmlElement
T someNumber;
}
@XmlRootElement
static class ContainerImpl<T extends Number> extends AbstractContainer<T> {
@SuppressWarnings("unused")
private ContainerImpl() {
// for JAXB
}
public ContainerImpl(final T someNumber) {
this.someNumber = someNumber;
}
}
/**
* @param args
*/
public static void main(final String[] args) throws Exception {
final AbstractContainer<Double> containerA = new ContainerImpl<>(42.5);
final JAXBContext context = JAXBContext.newInstance(ContainerImpl.class);
final Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
final StringWriter stringWriter = new StringWriter();
marshaller.marshal(containerA, stringWriter);
final String xmlString = stringWriter.toString();
System.out.println(xmlString);
final Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setEventHandler(event -> {
System.err.println("!! " + event.getMessage() + " - " + event.getLocator() + "\n");
return true;
});
final Object unmarshal = unmarshaller.unmarshal(new StringReader(xmlString));
System.out.println("unmarshal: " + unmarshal.toString());
}
}
对此有什么建议吗?谢谢!
最佳答案
我遇到了一个可能的解决方案(让我们称之为“解决方法”)来解决我的问题:
将@XmlElement T someNumber;
更改为@XmlElement(type = Object.class) T someNumber;
。这为 JAXB 提供了可实例化对象类的完全自由...实际上,返回的值对象是 Double 类型,因此在内部转换似乎有效...除了必须注释每个字段 - 还有其他注意事项吗?
关于java - JAXB:抽象绑定(bind)泛型类型的解码失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39104550/