i do know that what i am trying to do it isn't really possible with pure java - it is only possible if i look at the debug info. i will not compile without debug anyway, because a buch of my spring mvc would stop working.
that said, i have the following situation:
one generic superclass:
package com.cinefms.apitester.springmvc.crawlers;
public class TestGenerics<T extends TestGenericsInterface> {
public T get() {
return null;
}
public T put(T t) {
return null;
}
}
and its subclass:
package com.cinefms.apitester.springmvc.crawlers;
public class TestGenericsSub extends TestGenerics<TestGenericsImpl> {
}
with the objects in there being really damn simple.
an interface:
package com.cinefms.apitester.springmvc.crawlers;
public interface TestGenericsInterface {
}
and it's implementation:
package com.cinefms.apitester.springmvc.crawlers;
public class TestGenericsImpl implements TestGenericsInterface {
}
eclipse is perfectly fine figuring out that of TestGenericsSub.get()
should return an instance of TestGenericsImpl
... even if no source is available.
but how can i possible figure this out by myself at runtime?
if "m" is the Method "run", then
m.getGenericReturnType();
would return "T" (not helpful), while:
m.getReturnType();
gives me "TestGenericsInterface" (also not helpful). i have been looking at the "org.javaruntype" library ... but i can't seem to be able to figure it out.
could someone explain?
thanks!
Thanks to Java type erasure ( https://docs.oracle.com/javase/tutorial/java/generics/genTypes.html ), this is quite difficult. I suggest saving the class off as an attribute and then providing a getter if you absolutely must know the run-time type of T.
public class MyGenericClass<T> {
private final Class<T> type;
public MyGenericClass(Class<T> type) {
this.type = type;
}
public Class<T> getMyType() {
return this.type;
}
}
Otherwise you can try something like:
(Class<T extends TestGenericsInterface>) ((TestGenerics) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
I would prefer the former solution to the latter in code.
You can achieve that with ClassMate :
TypeResolver typeResolver = new TypeResolver();
MemberResolver memberResolver = new MemberResolver(typeResolver);
ResolvedType resolvedType = typeResolver.resolve(TestGenericsSub.class);
ResolvedTypeWithMembers resolvedTypeWithMembers = memberResolver.resolve(resolvedType, null, null);
ResolvedMethod resolvedGetMethod = resolvedTypeWithMembers.getMemberMethods()[0];
System.out.println(resolvedGetMethod.getReturnType()); // TestGenericsImpl
TypeTools is another option:
Class<?> t = TypeResolver.resolveRawArgument(TestGenerics.class, TestGenericsSub.class);
The result is as expected:
assert t == TestGenericsImpl.class;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.