如何保存使用我的注释的元素?

时间:2016-04-26 14:09:21

标签: java annotations annotation-processing

我使用继承自process()的类的方法AbstractProcessor来获取使用我的注释的元素的名称。

如何保存这些名称的列表,以便我可以在我的例子中使用它们。 main()方法?

@edit我有一个类ClassList,它将存储使用注释的类的名称@CustomAnnotation

public class ClassList {
    private static final List<String> classList= new LinkedList<>();

    public static List<String> getClassList() {
        return classList;
    }

    public static void addList(String name) {
        classList.add(name);
    }
}

这里我有@CustomAnnotation接口

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation{

}

以下是将处理注释的类的实现

@SupportedAnnotationTypes("com.example.CustomAnnotation")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class CompileTimeAnnotationProcessor extends AbstractProcessor {

    @Override
    public boolean process(Set<? extends TypeElement> annotations,
            RoundEnvironment roundEnv) {
        Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(CustomAnnotation.class);
        for (Element e : elements) {
            //adds each name to the list
            ClassList.addList(e.getSimpleName().toString());
        }
        //prints the array 
        System.out.println(Arrays.toString(ClassList.getClassList().toArray(new String[ClassList.getClassList().size()])));
        return true;
    }

}

然后我使用注释

@CustomAnnotation
public class AnnotatedClass {

}
@CustomAnnotation
public class TestClass {

}

现在,当我有main()方法时,我想访问这些类。

public static void main(String[] args) {
    System.out.println(ClassList.getClassList().size());
}

当我清理并构建它时确实在方法process()中打印数组,但随后我运行主程序列表为空。如何在主程序中访问该列表?

2 个答案:

答案 0 :(得分:2)

注释处理在编译时发生。您必须在运行时保留该信息。唯一的方法是将其写入一些永久存储(例如应用程序资源)。

  1. 至少RetentionPolycy.CLASS给出您的注释,以防万一。
  2. 在每个编译轮中执行搜索新的带注释元素并将其名称添加到Set中,就像您已经做的那样(提示:存储Name实例的工作原理一样好。)
  3. 在上一次编译期间,将该Set的内容写入某个资源文件(您可以在Google的Auto库中找到生成资源文件的注释处理器示例。)
  4. 阅读应用程序主要方法中的资源文件

答案 1 :(得分:2)

正如user1643723所述,处理器需要在编译时创建一个资源文件,然后您的应用程序可以在运行时读取该资源文件。以下是基于您的代码的示例。

要创建资源,您需要使用处理器Filer提供的processingEnv。这将在类基目录中创建一个文件:

Filer filer = processingEnv.getFiler();
FileObject resource = filer.createResource(StandardLocation.CLASS_OUTPUT, "", "classnames.txt", (Element[]) null);
Writer writer = resource.openWriter();
for (String className : ClassList.getClassList()) {
    writer.write(className);
    writer.write("\n");
}
writer.close();

现在,您可以像在任何其他资源中一样将其加载到应用程序中。

InputStream is = getClass().getResourceAsStream("/classnames.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = null;
while ((line = reader.readLine()) != null) {
    System.out.println(line);
}
reader.close();