Java注解处理器:检查TypeMirror是否实现了特定接口

17
我正在开发一个Java注解处理器。我的注解@foo用于标记可以在运行时从文件中读取或写入到文件的字段变量。然而,我希望在编译时检查变量类型是否实现了Serializable接口,以便如果字段不可序列化,我可以在编译时提供警告/错误。
(我不需要实际检查对象是否可序列化,如果它实现了Serializable接口,我会信任它)
我已经找出了如何做其他事情,但是我无法弄清楚如何检查元素是否实现了Serializable。我可以使用TypeElement#getInterfaces方法,但我无法弄清楚返回的任何这些TypeMirror是否都是Serializable的。
此外,如果有人知道任何好的java.lang.model或Java注解教程,那也将很有帮助。
编辑:我已经尝试过这个...
isSerializable = false  
for(TypeMirror tm : processingEnv.getTypeUtils().directSupertypes(em.asType()))  
{  
if(isSerializable = "java.io.Serializable".equals(tm.toString()))  
{  
break;  
}  
}  

对于实现了Serializable接口的String和Character类型来说,它们能够正常工作。但是对于继承自Number超类的Integer类型来说,就无法正常工作。

1个回答

34

不要检查直接的超类型,而应使用Types.isAssignable来检查Serializable是否是TypeMirror的一个超类型之一:

TypeMirror serializable = elementUtil.getTypeElement("java.io.Serializable").asType();
boolean isSerializable = typeUtil.isAssignable(tm, serializable);

2
运行得非常好!它更快、更干净,现在甚至可以接受像“int”这样的原始类型。=) - Testare
太棒了!正是我在寻找的。 - rpax
@kapep,我不小心给你的回答点了踩,如果你能编辑一下问题,我就可以撤销这个错误的投票。 - franmontiel
@franmontiel 没问题,我已经进行了编辑。感谢您告诉我。 - kapex
1
非常感谢你指出Types.isAssignable(…)这个方法,我一直在寻找这样的方法!请注意,如果你要比较的类型是参数化的(例如Collection<String>),你需要使用Types.isAssignable(…)和一个Collection<?>的类型镜像进行比较,你需要通过额外的步骤调用Types.getDeclaredType(…)来构造它。请参考我在类似问题的答案中,这个问题几乎是一个重复的问题,但是涉及到了泛型参数化的额外问题。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接