简体   繁体   English

如何通过泛型传递参数:类 <Clazz<G> &gt;

[英]How to pass parameter with generic: Class<Clazz<G>>

I try to parse a XML(String) to a Object using JAXB, but I can't find the way to call the method I had created because I don't know how to specify the class BasicRequest<G> with the SomeRequest as G 我尝试使用JAXB将XML(String)解析为对象,但是我找不到调用已创建方法的方法,因为我不知道如何使用SomeRequest作为G指定类BasicRequest<G>

public class XMLParser {

    public <G extends BaseRequest> BasicRequest<G> xmlToRequest(String xml, 
            Class<BasicRequest<G>> t) {
        BasicRequest<G> request = null;
        try {
            JAXBContext context = JAXBContext.instance(t);
            Unmarshaller m = context.createUnmarshaller();
            StringReader reader = new StringReader(xml);
            JAXBElement<BasicRequest<G>> unmarshal = m.unmarshal(new 
                StreamSource(reader), t);
            request = unmarshal.getValue();
        } catch (JAXBException ex) {
            //write log
        }
        return request;
    }
}

This are my classes: 这是我的课程:

public abstract class BaseRequest {
    protected String version;

    //getter & setter
}

,

public class SomeRequest extends BaseRequest {
    protected Integer id;

    //getter & setter
}

and

public class BasicRequest<G extends BaseRequest> {
    protected String user;
    protected G data;

    //getter & setter
}

All classes actually have the JAXB annotation correctly. 实际上,所有类都正确地具有JAXB批注。

If someone could please give me a hand on how should I call the method or a better way to define it I would appreciate. 如果有人可以帮助我,该如何调用该方法或更好的定义方法,我将不胜感激。

Perhaps someone better-versed in JAXB has a clever JAXB-centric solution, but from the standpoint of generics, I do not believe there is a way to do what you are trying to do. 也许某个精通JAXB的人有一个聪明的以JAXB为中心的解决方案,但是从泛型的角度来看,我认为没有一种方法可以做您想做的事情。 The type parameter information for the enclosing BasicRequest class is erased at runtime (see Class object of generic class (java) ), so any Class object representing a BasicRequest will simply reflect the raw type. 封闭的BasicRequest类的类型参数信息在运行时会被擦除(请参见泛型类(java)的 Class对象),因此任何表示BasicRequest Class对象BasicRequest将简单地反映原始类型。 (Correspondingly, the Unmarshaller will have no way to know what that parameter is intended to be.) (相应地, Unmarshaller将无法知道该参数的意图。)

You could try one of the following solutions: 您可以尝试以下解决方案之一:

  1. If you are certain that what the Unmarshaller returns will conform to BasicRequest, then you could cast the result to JAXBElement<BasicRequest<G>> . 如果确定Unmarshaller返回的内容符合BasicRequest,则可以将结果转换为JAXBElement<BasicRequest<G>> The cast will produce an unchecked cast warning (again, because of type erasure), which can be suppressed with the @SuppressWarnings("unchecked") annotation on the enclosing method, if you wish. 强制转换将产生未经检查的强制转换警告(同样由于类型擦除),如果需要,可以使用封闭方法上的@SuppressWarnings("unchecked")注释来@SuppressWarnings("unchecked")
  2. For each class you have which could take the place of G, you could create a subclass which extends BasicRequest parameterized with that class, ie: 对于可以代替G的每个类,您可以创建一个子类,该子类扩展使用该类参数化的BasicRequest,即:

     public class SomeBasicRequest extends BasicRequest<SomeRequest> { ... } 

    SomeBasicRequest would not be assignable from Class<BasicRequest<G>> , though, so you'd have to change the method header as follows: SomeBasicRequest ,不能从Class<BasicRequest<G>>分配Class<BasicRequest<G>> ,因此您必须按以下方式更改方法标头:

     public <G extends BaseRequest> BasicRequest<G> xmlToRequest(String xml, Class<? extends BasicRequest<G>> t) { ... } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM