I want to create a method that returns the class of parameterized type.
Consider an interface:
private static interface MyInterface<T> {
void run(T parameter);
}
And one implementation:
private static class MyInterfaceImplString implements MyInterface<String> {
@Override
public void run(String parameter) { }
}
Now, I want to pass MyInterfaceImplString.class to a method and this method will return String.class.
I am printing things around, and I can see the information be there but I am just unable to get it. Or at least with a safer way.
public class TypesTest {
public static void main(String[] args) {
Class<?> genericParameter1 = getGenericParamaterType(MyInterfaceImplVoid.class);
System.out.println(genericParameter1); //expect Void here
Class<?> genericParameter2 = getGenericParamaterType(MyInterfaceImplString.class);
System.out.println(genericParameter2); //expect String here
}
private static Class<?> getGenericParamaterType(Class<? extends MyInterface<?>> clazz) {
for (Method m : clazz.getMethods()) {
if ("run".equals(m.getName()) && m.getParameterCount() == 1) {
System.out.println(TypeLiteral.get(clazz).getParameterTypes(m));
}
}
return null;
}
private static class MyInterfaceImplVoid implements MyInterface<Void> {
@Override
public void run(Void parameter) { }
}
private static class MyInterfaceImplString implements MyInterface<String> {
@Override
public void run(String parameter) { }
}
private static interface MyInterface<T> {
void run(T parameter);
}
}
Ignore the null return value in the method. I just want to print things, see what I get and then return it. However, my current implementation seems kind of unorthodox because the class might have more than one run method that has nothing to do with MyInterface.
In case of a XY problem, I want be to able to recognize which of these implementations contain a parameterized type that extends Employee (let's say). I call the run method of the interface indirectly given an HourlyPaidEmployee or a MonthlyPaidEmployee. So, if the underlying implementation is MyInterface<Employee>, I can inject my actual employee (either is monthly or hourly paid). But if the implementation is MyInterface<HourlyEmployee>, I cannot inject a monthly paid one. So, getting the class of the parameterized type, helps me know what types of Employees I can inject safely to run method.
I am with java-8 and Guice dependency in classpath, which contains guava dependency.
EDIT: @Glorfindel made good point in his answer. But if the implementation looks like:
private static class MyInterfaceImplVoid implements MyInterface<Void> {
@Override
public void run(Void parameter) {
}
public void run(Integer par) {
}
}
I am not able to know what is the method that refers to the interface, hence his answer might return to me Integer.cass.