我正在尝试编写一个自定义的Anntoation处理器。 注释处理器将在编译时处理每个类文件以检查注释, 但是我怎么能得到它正在处理的课程呢? 我只能在以下代码中获取类名。
public class AnnotationProcessor extends AbstractProcessor {
......
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
Set<? extends Element> rootE=roundEnv.getRootElements();
for(Element e: rootE) {
if(e.getKind()==ElementKind.CLASS) {
String className= e.getSimpleName().toString();
processingEnv.getMessager().printMessage( javax.tools.Diagnostic.Kind.WARNING,className, e);
}
}
}
答案 0 :(得分:7)
您无法访问注释处理器正在处理的类,因为尚未编译该类。相反,Java提供了类似的Elements api,用于输入源的反射式检查。
元素(使用roundEnv.getRootElements()
找到的元素)提供了有关正在编译的类的更多信息,而不仅仅是其名称。使用ElementVisitors可以找到大量有用的信息:
http://docs.oracle.com/javase/6/docs/api/javax/lang/model/element/ElementVisitor.html http://docs.oracle.com/javase/6/docs/api/javax/lang/model/util/ElementKindVisitor6.html
包括类构造函数,方法,字段等。
以下是如何使用它:
public class AnnotationProcessor extends AbstractProcessor {
......
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Set<? extends Element> rootE=roundEnv.getRootElements();
for(Element e: rootE) {
for(Element subElement : e.getEnclosedElements()){
subElement.accept(new ExampleVisitor(), null); // implement ExampleVisitor
}
}
}
}
答案 1 :(得分:6)
Class<?>
对象,因为您希望定义的类正在正确编译!
如果您在未知的课程上致电getClass()
或使用Class<?> clazz = Class.forName("com.your.fancy.Class")
,您将获得java.lang.ClassNotFoundException
,这完全没问题。javax.lang.model.element.Element
和javax.lang.model.element.ExecutableElement
等类来描述/读取您的类定义。 javax.lang.model.*
有 javax.lang.model.type.TypeMirror
来描述课程,字段,方法等。ClassNotFoundException
为真,您也会获得roundEnvironment.processingOver()
。示例:
public static @Nonnull List getMethods(@Nonnull Element annotationElem, @Nonnull RoundEnvironment roundEnvironment) {
List outList = new ArrayList();
String simpleName = annotationElem.getSimpleName().toString();
for (Element elem : roundEnvironment.getRootElements())
if (elem.getSimpleName().toString().equals(simpleName))
for (Element methodDeclaration :elem.getEnclosedElements())
if (methodDeclaration instanceof ExecutableElement)
outList.add((ExecutableElement)methodDeclaration);
return outList;
}
public static TypeMirror getMethodFirstParam(@Nonnull ExecutableElement method, int n) {
List parameters = ((ExecutableElement) method).getParameters();
if (parameters != null && parameters.size() > 0)
return parameters.get(n).asType();
return null;
}
答案 2 :(得分:0)
有时您可以使用:subElement.getEnclosingElement()
以便您可以根据需要获取可能是类元素的父元素。