Вот простой пример, демонстрирующий проблему, связанную со стиранием, с которой я сталкиваюсь. У меня есть класс вроде этого:
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, так как я не владею или не управляю его источником.