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?
If we want the actual type of a generic parameter, we should inject it to the class in another way (e.g. constructor parameter, abstract function that returns the actual type, etc...).
Generic methods are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameter's scope is limited to the method where it is declared. Static and non-static generic methods are allowed, as well as generic class constructors.
Generic MethodsAll generic method declarations have a type parameter section delimited by angle brackets (< and >) that precedes the method's return type ( < E > in the next example). Each type parameter section contains one or more type parameters separated by commas.
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).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With