Я пытаюсь проанализировать 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 правильно.
Если бы кто-то мог, пожалуйста, дать мне понять, как я должен назвать метод или лучший способ его определить.
Возможно, у кого-то, кто лучше разбирается в JAXB, есть умное решение JAXB, но с точки зрения дженериков я не верю, что есть способ сделать то, что вы пытаетесь сделать. Информация о параметрах типа для вмещающего класса BasicRequest
удаляется во время выполнения (см. Объект класса универсального класса (java)), поэтому любой объект Class
представляющий BasicRequest
будет просто отображать исходный тип. (Соответственно, Unmarshaller
сможет узнать, каким должен быть этот параметр).
Вы можете попробовать одно из следующих решений:
JAXBElement<BasicRequest<G>>
результат к JAXBElement<BasicRequest<G>>
. Приведение будет выдавать предупреждение без предупреждения (опять же, из-за стирания @SuppressWarnings("unchecked")
), которое может быть подавлено с помощью @SuppressWarnings("unchecked")
по прилагаемому методу, если хотите.Для каждого класса, который у вас есть, который может заменить 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) {
...
}
Class<BasicRequest<SomeRequest>>
, но я не могу создать его экземпляр и, очевидно, не сработало, если я попробуюBasicRequest<SomeRequest>.class
. Я сейчас попробую ответить на Sumitsu.