java如何从typeElement获取实际类型?
我正在编写自定义注释处理器。虽然我能够处理没有泛型类型的类类型,但无法获得泛型类型的实际类型
MyBase界面
interface MyBase<T, S> {
void method1(S, T);
}
例1
public class KpA{
...
}
示例类2
public class KpB{
...
}
目标注释类
@MyAnnotation
interface MyHandler extends MyBase<KpA, KpB>{
}
处理代码段
TypeElement[] getActualTypes(ProcessingEnvironment pEnv, TypeElement element){
List<TypeElement> myBaseElement = element.getInterfaces().stream().map(v-> (TypeElement) pEnv.getTypeUtils().asElement(v)).collect(Collectors.toList());
myBaseElement.get(0).getTypeParameters().stream().forEach(System.out::println);
return null;
}
当ISysout
使用getTypeParameters时,我得到输出为S and T
;我怎样才能得到KpA and KpB
# 1 楼答案
当你处理类型系统时,准确地理解你想要什么是很重要的。您想要这些类型参数,是因为它们的类型变量在基类型的某些字段/方法中使用吗?例如,您的参数化基类型类似于
Collection<SomeItem>
,您想知道add
的返回类型吗?或者MyBase
是某种像Clonable
这样的标记接口,而你想要的是它的参数不管怎样;让我们假设,您的情况与问题中描述的完全一样:
MyBase
是某个接口,您只是出于未知的原因想要它的参数。这里有一个不灵活、愚蠢的方法来实现这一点:要获取第二个参数的类型(例如
KpB
):这里发生的事情如下:
DeclaredType
s(例如类和接口)诀窍在于对
directSupertypes
的调用:正如其文档中所解释的,该方法自动为您解析类型参数我们比较类型擦除(也称为原始类型),因为它们被期望以有意义的方式进行比较(这或多或少与比较类型元素相同)。请不要试图将泛型类型与
isSameType
进行比较——由于类型系统的工作方式,这肯定会产生令人惊讶的结果请注意,由于多重继承,上面的代码可能并不总是提供正确的结果:
MyHandler
可能从多个父级继承MyBase
,从而导致对T
和S
的真实身份的混淆。如果这些变量没有在任何地方使用(例如,我们谈论的是一个纯标记接口),它将仍然是一个谜:编译器不关心,所以没有人知道(我猜,您不想手动计算上/下限,是吗?)如果在某些方法/字段中使用了这些变量,那么您应该能够通过在MyHandler
上检查这些方法/字段来获取它们的类型(如何做到这一点是一个稍微棘手的问题,值得再问一个问题)