java - JAXB:抽象绑定(bind)泛型类型的解码失败

标签 java generics jaxb

如果匹配的 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/

相关文章:

java - 需要 JAXB 中的一个元素或另一个元素

java - 如何将 Java 枚举转换为 Typescript 枚举

java - 如何在调用方法 FileManager.get().loadModel(url) 期间获取 apache jena 中的 http 响应 header

c# - 如何将字符串数组转换为通用数组类型,同时允许非数组和数组作为类的通用类型参数?

java - 向使用泛型扩展父级的子级添加更多泛型类型

java - JAXB maven 插件只能在发生变化时生成源代码吗?

java - 单个应用程序有两个 list 文件?

java - 随机梯度下降未能在我的神经网络实现中收敛

Java,可以修改抽象类层次结构中父类(super class)的方法声明吗?

java - 字符引用 "&#x10"是无效的 XML 字符