简体   繁体   中英

Actual type of generic interface method parameter

This question has been answered when an implementing class is involved (which I don't have), but those methods are not working for me.

Let's say I have an an interface

public interface MySuperInterface<T> {
    public void test(T arg);
}

And then an extending interface

public interface MyInterface extends MySuperInterface<String> {

}

If I am iterating the methods of the MyInterface class, is it possible to get the actual type of the parameter (in this case String) of the 'test' method from the MyInterface class?

for (Method method : MyInterface.class.getMethods())
{
    for (Parameter parameter : method.getParameters())
    {
        final Class<?> paramClass = parameter.getType();
        System.out.println(paramClass);
    }
}

The above code will output 'class java.lang.Object'. Shouldn't I be able to tell that the parameter will be a String?

If you have the implementing interface that supplies the type argument explicitly, then this is possible with reflection; the below types used are imported from java.lang.reflect .

First get the Type object corresponding to the first super-interface.

Type tmi = MyInterface.class.getGenericInterfaces()[0];

In this case, tmi is really a ParameterizedType , a subinterface of Type . Cast it and get its type argument.

ParameterizedType ptmi = (ParameterizedType) tmi;
Type typeArg = ptmi.getActualTypeArguments()[0];

Because you supplied a class name as a type argument instead of another parameterized type or another type parameter, typeArg is a Class , which implements Type . Here, it's java.lang.Class .

System.out.println(typeArg);

class java.lang.String

You can use my utility class GenericUtil . It can resolve generic types.

Method m = MyInterface.class.getMethod("test", Object.class); // get the method
Type p = m.getGenericParameterTypes()[0]; // get the generic type 'T'
Map<TypeVariable<?>, Type> map = GenericUtil.getGenericReferenceMap(MyInterface.class); // get generic map of the class's context
System.out.println(map.get(p)); // get actual type for 'T'

output

class java.lang.String

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM