【问题标题】:Get "Class" object from generic type T从泛型类型 T 中获取“类”对象
【发布时间】:2021-09-26 06:18:35
【问题描述】:

我想创建返回 XML 文档的对象表示的通用函数(使用 JAXB)。我需要将“类”对象传递给 JAXBContext 构造函数,但是如何从 T 中获取它?

public <T> readXmlToObject(String xmlFileName, T  jaxbClass) {
   JAXBContext context = JAXBContext.newInstance(T.class); // T.class - here error, how to get it?
   .......
}

【问题讨论】:

  • 搜索“类型擦除”:-)

标签: java generics


【解决方案1】:

改为传递类对象,这很容易。

public <T> T readXmlToObject(String xmlFileName, Class<T>  jaxbClass) {
       JAXBContext context = JAXBContext.newInstance( jaxbClass ); // T.class - here error, how to get it?
       Object o = context.createUnmarshaller().unmarshal( new File( xmlFileName ) );
       return jaxbClass.cast( o );
}

这里的想法是,由于您无法从对象中提取类型参数,因此您必须反其道而行之:从类开始,然后操作对象以匹配类型参数。

【讨论】:

  • (我不认为? extends 在这里给你买任何东西。)
【解决方案2】:

别听别人的……你懂的。

只需将jaxbClass参数的类型改为Class&lt;T&gt;即可:

public <T> T readXmlToObject(String xmlFileName, Class<T> jaxbClass) {
   JAXBContext context = JAXBContext.newInstance(jaxbClass);
   .......
}

【讨论】:

    【解决方案3】:

    您无法在运行时获取类。 Java 使用类型安全擦除来实现泛型,这意味着对泛型类型的理解仅适用于编译。如果你想获得它的类,你必须在运行时询问实际的对象。

    【讨论】:

    • -1 错了!正在传入该类。问题在于方法签名
    • 感谢您的意见。正如所写的那样,它不起作用,但我明白你的意思是将输入更改为 Class 而不是 T。那很好。不过,如果因为 Java 的泛型 impl 不好而无需担心,那就太好了。
    【解决方案4】:

    尝试传递类本身,像这样

    public <T> readXmlToObject(String xmlFileName, Class<T> class) {
    

    【讨论】:

      【解决方案5】:

      看看this SO answer

      基本上,类型 T 在运行时不可用 - Java 泛型受制于 erasure by the compiler

      幸运的是,您已经有一个类的实例,因此您可以从那里获取类型信息:

      public <T> readXmlToObject(String xmlFileName, T jaxbClass) {
      
         // if jaxbClass is an instance of the data object, you can do this: 
         JAXBContext context = JAXBContext.newInstance(jaxbClass.getClass());
      
         // alternatively if jaxbClass is an instance of the Class object: 
         JAXBContext context = JAXBContext.newInstance(jaxbClass);
         // ......
      }
      

      【讨论】:

      • -1 完全行不通。 jaxbClass.getClass() 将返回 Class.class。你也错了 - 在这里擦除不是问题,因为正在传递类。
      • 啊 - 我假设因为它被限制为 T 而不是 Class 它是类的一个实例(如果你明白我的意思......)
      • 我明白你,但认为这是他的问题 - 他为参数编码了错误的类型。他没有传入T,因为在调用之前他不会有T 的实例,但他可以传入Class&lt;T&gt; 的实例。我承认我将使用参数名称jaxbClass,这非常强烈地表明它是class
      • 我不赞成这一点 - 你的回答并没有如此错,值得反对:)
      【解决方案6】:
      public class XYZ<T> {
          ...
          private Class<T> tClass;    
          ...
          public <T> readXmlToObject(String xmlFileName) {
             JAXBContext context = JAXBContext.newInstance(tClass);
             ...
          }
          ...
      } 
      

      【讨论】:

      • 我认为这行不通,因为 tClass 未初始化,您最终将 null 传递给“JAXBContext.newInstance(..)”调用。
      • 在我的代码中我是这样做的:private Class entityClass; final ParameterizedType type = (ParameterizedType)getClass().getGenericSuperclass(); entityClass = (Class)type.getActualTypeArguments()[0];
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-26
      • 2013-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多