Java泛型:获取泛型方法的返回类型

问题描述 投票:30回答:2

背景

我曾经写过这个方法:

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);

我的evaluate方法中的代码显然不起作用。 evaluator.evaluate()的第二个参数应该是一个Class对象。这导致我:

我的问题

如何获得泛型(返回)类型的类?作为评估的第二个参数,我应该用什么来代替T?

编辑:结论

Nicolas似乎是对的,它无法完成,我需要将类作为参数传递给我的方法。好处是,因为他的解决方案使参数化参数化在泛型类型上,我得到了对该参数的编译检查。

java generics jsp-tags
2个回答
45
投票

不幸的是,您肯定必须将您的方法更改为:

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

然后传递clazz作为你的第二个参数。没有你想象的那么短。


0
投票

您可以先创建一个通用对象,然后检索其参数化类型:

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子类对象,它可能表现不同。

© www.soinside.com 2019 - 2024. All rights reserved.