I'm trying to resolve all actual types of an implementation class relative to a generic class or interface.
I have written an ActualTypeArgumentsResolver
for this, but it only works when the TypeName remains consistent. I want to ignore the TypeName
and get all the actual types.
How can I achieve this?
Any help would be greatly appreciated. Thank you!
@Test
public void testIndirectlyExtendedGenericSuperclassWithDiffTypeName() {
abstract class AbstractClass3<AAA, BBB, CCC> { }
abstract class AbstractClass2<AA, BB, CC> extends AbstractClass3<CC, Map, BB> { }
abstract class AbstractClass1<A, B> extends AbstractClass2<Long, A, Boolean> { }
class Impl extends AbstractClass1<String, Integer> {}
Type[] arr = ActualTypeArgumentsResolver.resolve(Impl.class, AbstractClass3.class);
Assert.assertTrue(arr.length == 3);
Assert.assertEquals(arr[0], Boolean.class);
Assert.assertEquals(arr[1], Map.class);
Assert.assertEquals(arr[2], String.class);
}
Guava's TypeToken
supports this. Use the getSupertype
method on a TypeToken
representing Impl
to get the parameterised version of AbstractClass3
with all the actual type parameters.
var token = TypeToken.of(Impl.class);
var supertype = token.getSupertype(AbstractClass3.class).getType();
var typeArgs = ((ParameterizedType)supertype).getActualTypeArguments();
System.out.println(Arrays.toString(typeArgs));
// output:
// [class java.lang.Boolean, interface java.util.Map, class java.lang.String]