Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何构建用自定义注释注释的类列表?_Java_Annotations - Fatal编程技术网

Java 如何构建用自定义注释注释的类列表?

Java 如何构建用自定义注释注释的类列表?,java,annotations,Java,Annotations,我想获得应用程序中使用@Custom注释注释的类的完整列表。这种操作的最佳机制是什么 例如,JAX-RS实现如何找到用@Path注释的所有类?我希望使用相同的机制。在源代码上的IDE中运行查找,如果您试图在已编译的类上执行此操作,则必须向它们添加一个方法来支持此操作,即使您反编译了我认为不会显示注释或注释的类。您现在可能已经知道,Java无法枚举所有包或每个包中的类。所以你必须用“艰难”的方式去做。选项: 使用类似于grep的工具搜索注释。优点:快速,简单。缺点:可能返回误报(例如注释被注释掉的

我想获得应用程序中使用
@Custom
注释注释的类的完整列表。这种操作的最佳机制是什么


例如,JAX-RS实现如何找到用
@Path
注释的所有类?我希望使用相同的机制。

在源代码上的IDE中运行查找,如果您试图在已编译的类上执行此操作,则必须向它们添加一个方法来支持此操作,即使您反编译了我认为不会显示注释或注释的类。

您现在可能已经知道,Java无法枚举所有包或每个包中的类。所以你必须用“艰难”的方式去做。选项:

  • 使用类似于
    grep
    的工具搜索注释。优点:快速,简单。缺点:可能返回误报(例如注释被注释掉的类)

  • 编译代码并使用
    javap
    处理结果。它在字节码级别[*]上工作。它提供了准确的结果,但是
    javap
    的输出实际上并不用于自动处理

  • 使用像这样的字节码库。不适合胆小的人,但它允许您访问与注释相关的其他数据(如实现的接口、字段等)

  • 最后一个选项:Eclipse使用自己的Java编译器,它可以从Java代码构建AST(即使代码没有编译)。相对于ASM的优势:您可以免费获得Java代码的模型。使某些操作更简单。不过,设置起来并不那么容易


  • [*]:注释必须具有
    保留。运行时
    才能起作用。

    最简单的方法是使用IDE

    但你也可以

    • 编写一个日志,记录注释的所有引用
    • 编写一个AspectJ方面(我知道,警告可能不是您想要的,但AspectJ中没有信息)
    • 用于检查注释的字节码
    • 用于检查注释的源代码

    注意:所有这些都很棘手。AspectJ解决方案应该是最简单的。

    您应该看看

    通常使用称为类路径扫描的过程来完成。通常,类装入器不允许扫描类路径上的所有类。但通常唯一使用的类加载器是
    UrlClassLoader
    ,我们可以从中检索目录和jar文件列表(请参阅),并逐个打开它们以列出可用的类

    这种方法由像和这样的库实现

    另一种方法是编写注释处理器,该处理器将在编译时收集所有注释类,并构建索引文件供运行时使用

    上述机制在库中实现


    使用类路径扫描通常比编译时索引慢两个数量级。请参阅。

    我知道这是一个老问题,但我在自己的类路径扫描搜索中遇到了它,并找到了另一个很好的答案,所以我将其添加到这里

    有一个提供“尽力而为”类路径扫描的对象(实际上,这是所有类路径扫描实用程序提供的)。由于Guava是一个被广泛采用的、精心维护的实用程序库,对于(a)已经在使用Guava的项目,或者(b)需要一个稳定的库来进行类路径扫描的项目,这是一个很好的选择。

    是一个编译时注释扫描库,使用批注处理器实现。

    您可以尝试我的库:

    List classNames=新的FastClassPathScanner(“com.mypackage”)
    .scan()
    .getNamesofClassswithanNotation(Custom.class);
    
    您想在源代码(.java)或编译代码(.class)中搜索吗?不,我不使用任何IDE。我只对JAR中的编译代码感兴趣。@Brian是的,如果注释的
    @Retention
    RUNTIME
    。。。如果它们是用
    @Retention(RUNTIME)
    First Option=arggghh定义的。所有其他:+1您的JAX-RS实现使用了哪些选项(例如,泽西岛)来查找所有
    @Path
    -注释类?是否愿意为您的说法提供证据,证明没有办法?特别是考虑到我在回答中链接到的图书馆,这是正确的;请注意,运行时的类路径可能不同于编译时的类路径。因此类路径扫描是脆弱的。当代码在应用程序服务器中运行或使用自定义类加载器时,检查系统属性
    java.class.path
    可能会导致错误的结果。并非所有类加载器都允许检查类从何处加载的路径。因此,我的主张是:Java没有API来实现这一点。你必须求助于某种黑客手段。我只想指出,你实际上可以在运行时获得这些信息,但你需要使用反射来在你正在使用的类加载器上公开“classes”属性。这是不推荐的,在较新版本的Java中可能会中断(不能保证在下一版本中会有私有方法)。更多信息请访问
    List<String> classNames = new FastClassPathScanner("com.mypackage")
        .scan()
        .getNamesOfClassesWithAnnotation(Custom.class);