【问题标题】:Java generics: get class of generic method's return typeJava泛型:获取泛型方法的返回类型的类
【发布时间】:2011-05-11 23:14:25
【问题描述】:

背景

我曾经写过这个方法:

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() 的第二个参数应该是一个 Class 对象。这导致我:

我的问题

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

编辑:结论

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

【问题讨论】:

    标签: java generics jsp-tags


    【解决方案1】:

    很遗憾,您肯定必须将方法更改为:

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

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

    【讨论】:

    【解决方案2】:

    这不适用于所有 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&lt;&gt; 对象,而是TypeVariableImpl 子类对象,它们的行为可能不同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多