Как передать параметр с помощью generic: Class <Clazz <G >>

1

Я пытаюсь проанализировать XML (String) для объекта с использованием JAXB, но я не могу найти способ вызвать метод, который я создал, потому что я не знаю, как указать класс BasicRequest<G> с SomeRequest как 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;
    }
}

Это мои классы:

public abstract class BaseRequest {
    protected String version;

    //getter & setter
}

,

public class SomeRequest extends BaseRequest {
    protected Integer id;

    //getter & setter
}

а также

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

    //getter & setter
}

Все классы на самом деле имеют аннотацию JAXB правильно.

Если бы кто-то мог, пожалуйста, дать мне понять, как я должен назвать метод или лучший способ его определить.

  • 0
    Какую ошибку и / или вывод вы видите?
  • 0
    В основном, чтобы вызвать этот метод, мне нужно было передать определение класса что-то вроде этого Class<BasicRequest<SomeRequest>> , но я не могу создать его экземпляр и, очевидно, не сработало, если я попробую BasicRequest<SomeRequest>.class . Я сейчас попробую ответить на Sumitsu.
Теги:
jaxb
generic-programming

1 ответ

0
Лучший ответ

Возможно, у кого-то, кто лучше разбирается в JAXB, есть умное решение JAXB, но с точки зрения дженериков я не верю, что есть способ сделать то, что вы пытаетесь сделать. Информация о параметрах типа для вмещающего класса BasicRequest удаляется во время выполнения (см. Объект класса универсального класса (java)), поэтому любой объект Class представляющий BasicRequest будет просто отображать исходный тип. (Соответственно, Unmarshaller сможет узнать, каким должен быть этот параметр).

Вы можете попробовать одно из следующих решений:

  1. Если вы уверены, что то, что возвращает Unmarshaller, будет соответствовать BasicRequest, тогда вы можете JAXBElement<BasicRequest<G>> результат к JAXBElement<BasicRequest<G>>. Приведение будет выдавать предупреждение без предупреждения (опять же, из-за стирания @SuppressWarnings("unchecked")), которое может быть подавлено с помощью @SuppressWarnings("unchecked") по прилагаемому методу, если хотите.
  2. Для каждого класса, который у вас есть, который может заменить G, вы можете создать подкласс, который расширяет BasicRequest, параметризованный этим классом, то есть:

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

    SomeBasicRequest не будет Class<BasicRequest<G>>, однако, поэтому вам нужно будет изменить заголовок метода следующим образом:

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню