有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java反射:如何获得评论?

我在Java解析方面遇到了一些困难。我需要通过反射来获得类、字段、方法等的注释

我发现了JavaParser,看起来它可以引发评论,但我不知道怎么做,因为所有的例子都只是解析给定的字符串。我发现TypeSolver可以使用规范名称,但它似乎无法处理注释

我的问题是,如果我只有Class<?>,而且该项目还有其他一些jar's也应该反思,如何找到评论。通过调试,我看到了原始的源代码,似乎可以以某种方式完成
谢谢

另外,我有源代码,我需要将Class<?>与源代码匹配,然后通过JavaParser提取注释


共 (3) 个答案

  1. # 1 楼答案

    首先,不能使用反射直接获取注释,也不能使用读取“.class”文件的库获取注释。该信息不存在于“.class”文件中,反射只知道从那里可以直接获得信息

    正如人们所指出的,只有拥有源代码才能获得评论。如果你有一个源代码文件,你应该能够使用JavaParser或(可能)其他库来提取注释。。。或者编写自己的解析器

    问题是从Class对象映射到相应的源代码文件。假设应用程序的类路径上有多个JAR对应的多个源树。你需要:

    • 类路径上每个JAR或目录的URI
    • 从每个URI到相应源树的映射

    方法是:

    1. Class对象获取完全限定的类名
    2. 将类名映射到相对的Java源路径;e、 g.foo.bar.Baz将变成foo/bar/Baz.java
    3. 使用clazz.getProtectionDomain().getCodeSource().getLocation().toURI()获取从中加载类的URI
    4. 将URI映射到相应的源目录树。。。使用映射
    5. 解析相对于源树根的相对路径
    6. 打开源文件

    上述一些步骤可能会带来问题。例如:

    • 在第2步中,需要处理嵌套类
    • 在步骤3中,getCodeSource()可以返回null
    • 在步骤3中,生成的URI可能有一个奇怪的协议
    • 如果映射不完整,第4步可能会失败
    • 如果源代码与正在执行的代码不匹配,则步骤5可能会失败

    打开源文件后,构建一个Reader并解析源代码。。。使用您选择的Java解析器


    如果您的项目是“绿色领域”项目,那么定义自定义注释类型(retention==runtime)并将注释转换为注释可能会更简单。可以简单快速地提取这些注释,而不存在上述任何可能的故障模式


    I haven't got how to do it as all the [JavaParser] examples just parse given string.

    javadoc显示可以使用JavaParser实例来解析FileInputStreamReaderString

  2. # 2 楼答案

    如果你有源代码,它可能是一个JAR文件的形式。在JAR文件中定位源文件非常容易,因为该类提供了包和本地名称。您必须考虑嵌套类的情况,但其实很容易实现。

    找到源文件后,可以使用JavaParser轻松解析并检索注释:

        String classText = "public class Dummy{\n" + "//Comment\n" + "}";
        StringReader reader = new StringReader(classText);
        CompilationUnit compilationUnit = JavaParser.parse(reader, true);
    
        for (Comment comment : compilationUnit.getAllContainedComments()) {
            System.out.println(comment.getContent());
        }
    
  3. # 3 楼答案

    您应该创建注释类,并为您的需求获取价值。例如:

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.FIELD})
    public @interface Report {
        String value();
    }
    
    
    
    public class ReportClass{
        @Report("this is comment")
        private String atmLastTrxAmount;
    }
    
    
    
    for (Field declaredField : ReportClass.class.getDeclaredFields()) {
        declaredField.setAccessible(true);
        String relatedFieldComment = declaredField.getAnnotation(Report.class).value();
        ...
    }