[英]Java generics: get class of generic method's return type
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).这很好用(尽管我在研究当前问题时在这里的答案中看到这是容易出错的)。
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. evaluator.evaluate()
的第二个参数应该是一个类对象。 This leads me to:这导致我:
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 作为要评估的第二个参数?
Nicolas seems to be right, it can not be done and I need to pass the class as an argument to my method. Nicolas 似乎是对的,这是不可能的,我需要将类作为参数传递给我的方法。 The upside is that since his solution makes the argument parametrized on the generic type I get a compilation check on that argument.好处是,由于他的解决方案使参数在泛型类型上参数化,我得到了对该参数的编译检查。
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.然后将clazz
作为第二个参数传递。 Not as short as you expected.没有你想象的那么短。
This doesn't work with all JVM!这不适用于所有 JVM!
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.你得到的不是Class<>
对象,而是TypeVariableImpl
子类对象,它们的行为可能不同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.