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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4213972/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 14:39:25  来源:igfitidea点击:

Java generics: get class of generic method's return type

javagenericsjsp-tags

提问by Peter Jaric

Background

背景

I once wrote this method:

我曾经写过这个方法:

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

It's supposed to be called like this:

应该这样称呼:

Set<String> set = createSortedSet();

This works fine (although I've seen in answers here when researching the current question that this is error-prone).

这很好用(尽管我在研究当前问题时在这里的答案中看到了这很容易出错)。

The current situation

目前的情况

Anyway, now I am writing the following code (in a class that extends javax.servlet.jsp.tagext.TagSupport):

无论如何,现在我正在编写以下代码(在扩展 javax.servlet.jsp.tagext.TagSupport 的类中):

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

The purpose is to be able to call this like:

目的是能够像这样调用它:

Integer width = evaluate(widthStr);

The code in my evaluate method obviously doesn't work. The second argument to evaluator.evaluate()is supposed to be a Class object. This leads me to:

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

My question

我的问题

How can I get the Class of a generic (return) type? What should I write in place of T as the second argument to evaluate?

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

EDIT: Conclusion

编辑:结论

Nicolas seems to be right, it can not be done and I need to pass the class as an argument to my method. The upside is that since his solution makes the argument parametrized on the generic type I get a compilation check on that argument.

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

采纳答案by Nicolas

Unfortunately, you will certainly have to change your method to:

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

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

and then pass clazzas your second parameter. Not as short as you expected.

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

回答by Fabrice TIERCELIN

You can first create a generic object and then retrieve its parameterized type:

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

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

Beware! You don't get a Class<>object, you get a TypeVariableImplsubclass object, which may behave differently.

谨防!你得到的不是一个Class<>对象,而是一个TypeVariableImpl子类对象,它的行为可能不同。