假设我有这个注释
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Name
{
String value();
}
Run Code Online (Sandbox Code Playgroud)
这将按如下方式使用
@Name("name1")
public static Foo foo = new Foo();
Run Code Online (Sandbox Code Playgroud)
我的项目源文件中有多个这些。是否有一种相当简单的方法来搜索和收集所有以 开头的“foo” @Name?换句话说,我想写一个方法来返回一个Set<Foo>包含这些的。
谢谢!!!
我不太熟悉其他人建议的类路径扫描程序。它们似乎是一个强大的 - 如果不是理想的 - 解决方案。
如果您可以控制源,那么您可以使用注释处理。
创建一个注释处理器,该处理器将创建一个MapClass具有静态成员的类Map<String,Foo>。每次注释处理器遇到 @Name 注释时,它都会将其添加到MapClass. 当它完成对注释的处理后,它将具有与您对地图进行硬编码的效果相同的效果。
注释处理发生在编译期间。如果您项目中的某些类不是您编译的。例如,如果其他人编译了一些类并给了你一个 jar,那么它就不会那么容易工作。但是如果所有的类都是由你编译的,那么这应该不是问题。
要创建注释处理器,请扩展AbstractProcessor. 您将需要使用注释来注释您的类@ SupportedAnnotationTypes ( "Name" )(确保 name 是您的注释的完全限定名称。
覆盖该process方法。 process有两个参数: annotations和roundEnv。 annotations只是这个特定处理器支持的一组注释 - 在你的情况下它应该是(名称)。 roundEnv是一个有用的实用程序类。
遍历 中的一个注解annotations。使用roundEnv到getElementsAnnotatedWith。这应该为您提供带有@Name注释的所有元素的集合。
AbstractProcessor有另一个实用程序成员 - processingEnv。使用它的getFiler方法来createSourceFile.
然后你必须稍微修改你的编译。您必须在其他类之前单独编译您的处理器。在编译处理器并且您正在编译其他类之后,您必须告诉编译器有关您的处理器的信息。如果您使用命令行,则需要添加-processorpath /path/to/processor/class[es]和-processor qualified.name.of.processor。
这种方法相对于类路径扫描器的优点是一切都在编译时发生。因此,例如,如果您不小心@Name向Bar元素添加了注释,那么您可以让处理器抛出编译时错误(如果您希望处理器可以忽略它)。然后您可以在产品发货前修复它。使用类路径扫描器,抛出的任何错误都是运行时错误 - 用户将看到。
这种方法的缺点也是一切都发生在编译时。这使得向项目动态添加类变得更加困难。
| 归档时间: |
|
| 查看次数: |
1613 次 |
| 最近记录: |