Ответ в том, что вы не можете, по крайней мере, со сложными обобщенными типами, такими как Collection<Integer>
.
Тип Integer
не ограничен, это означает, что вы сможете увидеть его только как Object
.
Единственный способ узнать, что Collection
несет определенный тип данных, - это содержать хотя бы один элемент.
Лучшее, что вы можете получить, это что-то похожее на
private static final Map<Class<?>, Function<Object, Class<? extends StudentResponseReport<?>>>>
TYPES = new IdentityHashMap<>();
static {
TYPES.put(String.class, object -> StudentResponseReportSAQ.class);
TYPES.put(Collection.class, object -> {
final var collection = (Collection<?>) object;
final var element = collection.stream()
.findFirst()
.orElse(null);
if (element != null && Integer.class.isAssignableFrom(element.getClass())) {
return StudentResponseReportMCQ.class;
}
throw new UnsupportedOperationException("...");
});
}
private <T> StudentResponseReport<?> convert(
final long roundId,
final T response)
throws NoSuchMethodException,
IllegalAccessException,
InvocationTargetException,
InstantiationException {
for (final var entry : TYPES.entrySet()) {
if (entry.getKey().isAssignableFrom(response.getClass())) {
final var classToInstantiate = entry.getValue().apply(response);
// Pass whatever you want to the constructor
return classToInstantiate.getConstructor().newInstance();
}
}
throw new UnsupportedOperationException("...");
}
И это только с двумя типами. Я действительно не рекомендую делать это.