Reputation: 2997
Is there a way get the return type of a generic method- return type?
public interface MyGeneric<T> {
T doSomething();
}
public interface MyElement extends MyGeneric<Element> {
}
public class Main {
public static final void main(String[] args) {
System.out.println(MyElement.class.getMethod("doSomething", new Class<?>[0]).magic()); // => Element
}
}
Using Method.getReturnType() I get java.lang.Object without. Does the method "magic" exist?
Upvotes: 7
Views: 18144
Reputation: 25623
Unfortunately, the reflection capabilities in the core Java library are rather poor for analyzing generic types. You can use the getGeneric...
methods (e.g., getGenericReturnType()
), but they don't work all that well, and they usually return Type
instances instead of Class
instances. I find this very clumsy to work with.
I have written my own reflection API, based the .NET's, which I feel is more consistent (particularly where generics are concerned). Consider the following output:
import com.strobel.reflection.Type;
interface MyGeneric<T> {
T doSomething();
}
interface Element {}
interface MyElement extends MyGeneric<Element> {}
class Main {
public static final void main(String[] args) throws NoSuchMethodException {
// prints "class java.lang.Object":
System.out.println(
MyElement.class.getMethod("doSomething").getReturnType()
);
// prints "T":
System.out.println(
MyElement.class.getMethod("doSomething").getGenericReturnType()
);
// prints "Element":
System.out.println(
Type.of(MyElement.class).getMethod("doSomething").getReturnType()
);
}
}
You're welcome to use my library. I actually just committed a bug fix that prevented this example from working (it's in the tip of the develop
branch).
Upvotes: 8
Reputation: 19002
No, that magic does not exist generally. If you want to make a trick in order to get to that data, you can require that data in your interface like explained here.
On the other side, if your type is special (like a List), you can do that. See this answer for special types.
Upvotes: 1