Reputation: 544
Is there any way to understand what type will be returned by the method called from generic class?
There is an example:
Generified<Integer, Double> generified = new Generified<Integer, Double>();
Method method = generified.getClass().getMethod("getDoubleValue");
Class<?> returnType = ........
Ok guys, there is class:
public class Generified<T, Z> {
private T tValue;
private Z doubleValue;
private List<T> tValueList;
public Generified() {
}
public T gettValue() {
return tValue;
}
public void settValue(T tValue) {
this.tValue = tValue;
}
public Z getDoubleValue() {
return doubleValue;
}
public void setDoubleValue(Z doubleValue) {
this.doubleValue = doubleValue;
}
public List<T> gettValueList() {
return tValueList;
}
public void settValueList(List<T> tValueList) {
this.tValueList = tValueList;
}
}
Update:
There is why I'm asking for:
I'm trying to do the lib which can do simple aggregations for collections. There is what I have for now: github.README.md
But I have a lot of issues with return types from the methods of generified classes. I need to know the real return type to wrap it with CGLIB and add interceptor for all method for this return class to know in the future of the call hierarchy.
But after a lot of debugging I see that there is now way to do what I want and I want to cry :)
Upvotes: 4
Views: 164
Reputation: 122449
I don't understand what the problem is. You know from .getGenericReturnType()
that the return type is Z
. And you know Z
is the second parameter. And you are explicitly creating an object with a concrete parameter, Double
, in the first line. So you know exactly what it is.
Upvotes: 0
Reputation: 2840
You could declare Generified as an abstract class, that way to instantiate it you must use a subclass and when you do that you can use getClass().getGenericSuperclass() inside the Generified constructor and retrieve the actual type parameters passed in, like:
package com.stackoverflow.q15998449;
import java.lang.reflect.ParameterizedType;
import java.util.List;
public abstract class Generified<T, Z>
{
private T tValue;
private Z doubleValue;
private List<T> tValueList;
private final Class<Z> zType;
private final Class<T> tType;
@SuppressWarnings("unchecked")
public Generified()
{
ParameterizedType a = ((ParameterizedType) getClass().getGenericSuperclass());
tType = (Class<T>) a.getActualTypeArguments()[0];
zType = (Class<Z>) a.getActualTypeArguments()[1];
}
public Class<T> getTReturnType()
{
return tType;
}
public Class<Z> getZReturnType()
{
return zType;
}
public T gettValue()
{
return tValue;
}
public void settValue(T tValue)
{
this.tValue = tValue;
}
public Z getDoubleValue()
{
return doubleValue;
}
public void setDoubleValue(Z doubleValue)
{
this.doubleValue = doubleValue;
}
public List<T> gettValueList()
{
return tValueList;
}
public void settValueList(List<T> tValueList)
{
this.tValueList = tValueList;
}
A user of your class would then look like:
package com.stackoverflow.q15998449;
import java.lang.reflect.Method;
public class User
{
public static void main(String[] args) throws NoSuchMethodException, SecurityException
{
Generified<Integer, Double> generified = new Generified<Integer, Double>(){};
Method method = generified.getClass().getMethod("getDoubleValue");
Class<?> returnType = generified.getZReturnType();
}
}
Upvotes: 2
Reputation: 2416
The answer is obvious from the method name - getDoubleValue()
should return Double
. But since you didn't provide code for that class we can only guess.
But if you are talking general case here, reflection can only go so far: Method.getReturnType() and Method.getGenericReturnType().
UPDATE:
If you check MethodSpy
on this page and run it against your class you'll get:
public Z Generified.getDoubleValue()
ReturnType: class java.lang.Object
GenericReturnType: Z
I don't think you can find what you're looking for just by looking at the generic class, it just doesn't contain the information you need. Hope this helps.
Upvotes: 2