Вот простой пример, демонстрирующий проблему, связанную со стиранием, с которой я сталкиваюсь. У меня есть класс вроде этого:
public abstract class AbstractHandler<T> {
...
public abstract Class<T> handledType();
}
Тогда у меня есть эта реализация:
public class ConcreteHandler extends AbstractHandler<Map<String, List<Thing>>> {
@Override
public Class<Map<String, List<Thing>>> handledType() {
//what do I return here?!
}
}
Я не могу вернуть Map<String, List<Thing>>.class
, так как это даже не действует синтаксически. Я попытался сделать общий тип параметра в подтипе HashMap<String, List<Thing>>
, а затем возвратить new HashMap<String, List<Thing>>().getClass()
, но это не работает, потому что тип возврата Class<T>#getClass()
равен Class<? extends T>
. Я посмотрел на TypeToken
из Guava, а метод getRawType
выглядел многообещающим, но он возвращает Class<? super T>
.
У меня есть обходное решение, которое выглядит так:
public class ThingListMap {
private Map<String, List<Thing>> thingListMap;
...
}
и я просто использую ThingListMap
как общий тип-параметр.
Другим возможным обходным путем является выполнение принудительного ввода:
public Class<Map<String, List<Thing>>> handledType() {
return (Class<Map<String, List<Thing>>>) new HashMap<String, List<Thing>>().getClass();
}
Есть ли более элегантный способ сделать это?
EDIT: В ответ на один из ответов я не могу изменить подпись метода handledType
, так как я не владею или не управляю его источником.