Первое, что приходит в голову для решения – дженерик-параметр. Такой подход не сработает, потому что тип будет стёрт во время компиляции, а логика будет происходить позже, во время выполнения.
Решение, которое сработает для многих случаев – объявление в методе аргумента типа
Class<T>
. Пользователь будет передавать в него значение Foo.class
или fooInstance.getClass()
. Проблемы с ним начинаются, когда становится нужно передать generic-тип. Синтаксис .class
не поддерживает дженерики, а .getClass()
от экземпляров List<String>
и List<Integer>
вернет один и тот же объект-описание сырого типа List
.На помощь приходит техника, описанная в предыдущей публикации.
1. Объявляется generic класс-обертка над типом:
TypeInformation<T>
;. Наш метод будет принимать информацию о типе в виде экземпляра этой обертки.2. В обертку добавляется конструктор с видимостью protected. Теперь можно создавать объекты только наследников, но не самого этого типа.
3. Пользователь будет передавать экземпляр анонимного наследника обертки:
new TypeInformation<List<String>>() {}
.4. Внутри вызов
getClass().getGenericSuperclass()
вернет ParameterizedType
. Это будет описание типа родителя анонима, то есть самой обертки. Из него с помощью getActualTypeArguments()
можно достать рантайм-информацию о значении дженерика (о List<String>
).