Подтвердить что ты не робот

Java generics: получить класс типа возвращаемого типа

Фон

Я однажды написал этот метод:

private <T> SortedSet<T> createSortedSet() {
  return new TreeSet<T>();
}

Он должен быть вызван следующим образом:

Set<String> set = createSortedSet();

Это работает отлично (хотя я видел ответы здесь, когда исследую текущий вопрос, что это подвержено ошибкам).

Текущая ситуация

В любом случае, теперь я пишу следующий код (в классе, который расширяет javax.servlet.jsp.tagext.TagSupport):

private <T> T evaluate(String expression) {
  ExpressionEvaluator evaluator = pageContext.getExpressionEvaluator();
  return evaluator.evaluate(expression, T, null, pageContext.getVariableResolver());
}

Цель состоит в том, чтобы иметь возможность называть это следующим образом:

Integer width = evaluate(widthStr);

Код в моем методе оценки явно не работает. Второй аргумент evaluator.evaluate() должен быть объектом класса. Это приводит меня к:

Мой вопрос

Как я могу получить класс универсального (возвращаемого) типа? Что я должен писать вместо Т в качестве второго аргумента для оценки?

EDIT: Заключение

Николя кажется прав, это не может быть сделано, и мне нужно передать класс в качестве аргумента для моего метода. Положительным моментом является то, что, поскольку его решение делает параметр параметризованным для общего типа, я получаю проверку компиляции этого аргумента.

4b9b3361

Ответ 1

К сожалению, вам, безусловно, придется изменить свой метод на:

private <T> T evaluate(Class<T> clazz, String expression)

а затем передайте clazz в качестве второго параметра. Не так коротким, как вы ожидали.

Ответ 2

Вы можете сначала создать универсальный объект, а затем получить его параметризованный тип:

private <T> T evaluate(String expression) {
  List<T> dummy = new ArrayList<>(0);
  Type[] actualTypeArguments = ((ParameterizedType) dummy.getClass().getGenericSuperclass()).getActualTypeArguments();
  Type clazz = actualTypeArguments[0];
  Class<T> theClass = (Class<T>) clazz.getClass();

  ExpressionEvaluator evaluator = pageContext.getExpressionEvaluator();
  return evaluator.evaluate(expression, theClass, null, pageContext.getVariableResolver());
}

Осторожно! Вы не получаете объект Class<>, вы получаете TypeVariableImpl подкласса TypeVariableImpl, который может вести себя по-разному.