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

42

背景

我曾经写过这个方法:

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对象。这让我想到:

我的问题

我如何获取泛型(返回)类型的Class?我应该在evaluate的第二个参数的位置写什么?

编辑:结论

Nicolas似乎是正确的,它无法完成,我需要将类作为参数传递给我的方法。好处是,由于他的解决方案使参数参数化为泛型类型,因此我可以对该参数进行编译检查。

2个回答

57

很遗憾,您肯定需要改变您的方法为:

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

然后将clazz作为第二个参数传递。不像你期望的那么简短。


2
谢谢!在尝试了各种基于反射的想法后,我不能不同意你的观点。 - Peter Jaric
5
基本上问题存在是因为http://docs.oracle.com/javase/tutorial/java/generics/erasure.html。 - maxammann

3

#ff0000 这不能适用于所有的JVM!

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

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子类对象,它可能会有不同的行为。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接