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

家住魔仙堡 提交于 2019-12-17 11:21:14

问题


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

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:

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?

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.


回答1:


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

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

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




回答2:


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 TypeVariableImpl subclass object, which may behave differently.



来源:https://stackoverflow.com/questions/4213972/java-generics-get-class-of-generic-methods-return-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!