1

Say I have a ParameterizedType with a specific type: Container<Integer>, how can I get from it the non-specific type: Container<E>.

I want to be able to match the type argument E with its concrete value Integer.

Just to make it clear, I am NOT interested in the common question of getting the Int out of a Container<Integer> field.

harel
  • 515
  • 5
  • 20

2 Answers2

2

This can be more tricky than described because the type variable may also be coming from anywhere in the hierarchy, and the variable index can easily change at each level. E.g.:

interface Container<E, T> {
}

//Notice how E, T became T, E, so indices can not be trusted
interface SubContainer<E, T> extends Container<T, E> {
}

This means you'd need to walk the hierarchy and collect variables at each level.

I suggest you use GeAnTyRef for similar scenarios as it already takes care of complexities (and might already have a way to do what you're after without doing the variable resolution yourself):

Type resolved = new TypeToken<Container<Integer>>(){}.getType(); //or get the instance in any way you already do    
TypeVariable variable = Container.class.getTypeParameters()[0];

GenericTypeReflector.getTypeParameter(resolved, variable); //Gets you Integer

Disclosure: I am the maintainer of GeAnTyRef lib

kaqqao
  • 10,809
  • 4
  • 50
  • 101
1

The ParameterizedType lets you get its raw type version with ParameterizedType#getRawType(). That will return a Type value that will be a Class (afaik, there might be edge case where it is not), so cast it. Then use the Class to get the corresponding type parameters with Class#getTypeParameters().

For example

 public class Sample {

    public static void main(String args[]) throws Exception {
        ParameterizedType type = (ParameterizedType) IntegerContainer.class.getGenericInterfaces()[0];
        Class<?> rawType = (Class<?>) type.getRawType();
        TypeVariable<? extends Class<?>>[] typeVariables = rawType.getTypeParameters();
        System.out.println(Arrays.toString(type.getActualTypeArguments()));
        System.out.println(Arrays.toString(typeVariables));
    }
}

interface Container<E> {
}

interface IntegerContainer extends Container<Integer> {
}

prints

[class java.lang.Integer]
[E]

Elements will be at the same indices in their respective arrays.

Sotirios Delimanolis
  • 252,278
  • 54
  • 635
  • 683