如何在运行时获取方法的JavaDoc?

35

在运行时很容易获取Class方法名称
但是
我如何在运行时获取JavaDoc的方法呢?

如下面的例子所示

我们的类包含我们目标方法的JavaDoc

public class MyClass {
    /**
     * 
     * @param x value of ....
     * @return result of ....
     */
    public String myMethod(int x) {
        return "any value";
    }

}

我们的类有一个主方法

public class TestJava {
    public static void main(String[] args) {
        // get Class method Name at run time
        String methodName = MyClass.class.getMethods()[0].getName();
        System.out.println(methodName); // will print myMethod
        // How to  get a JavaDoc of myMethod `method` at run time
        // MyClass.class.getMethods()[0].????
        // expected to print a JavaDoc of myMethod
    }
}

1
你说的“在运行时”是什么意思?简短的回答是你不需要关心。 - Dave Newton
出于什么目的?运行程序的用户几乎肯定不是程序员:向他展示Javadoc有什么好处呢? - user207421
2
这实际上是Groovy 3的一个新功能。我可以看到这将成为为REST API提供文档的新方式,例如使用Swagger。 - John Mercier
5个回答

25

唯一在运行时获取它的方法是使用自定义注释。

创建一个自定义注释类:

@Retention(RUNTIME)
@Target(value = METHOD)
public @interface ServiceDef {
  /**
   * This provides description when generating docs.
   */
  public String desc() default "";
  /**
   * This provides params when generating docs.
   */
  public String[] params();
}

将其用于类的方法,例如:

@ServiceDef(desc = "This is an utility class",
            params = {"name - the name","format - the format"})     
public void read(String name, String format)

通过反射检查注释:

for (Method method : Sample.class.getMethods()) {
  if (Modifier.isPublic(method.getModifiers())) {
    ServiceDef serviceDef = method.getAnnotation(ServiceDef.class);
    if (serviceDef != null) {
      String[] params = serviceDef.params();
      String descOfMethod = serviceDef.desc();
    }
  }
}

请问您能提供一个例子吗? - Ahmed Nabil
7
最大的问题仍然是需要同步/维护Javadoc和注释字符串常量。 - Aquarius Power
我建议使用两个不同的注释,可能是@Params和@Brief。 - Johannes

19

注解处理器可以访问源代码中的Javadoc注释。如果您可以控制您所感兴趣的Javadoc类的编译过程,您可以使用注解处理器在编译时获取Javadoc,并在运行时提供它。

这就是therapi-runtime-javadoc项目所使用的方法(声明:我是作者,正在不遗余力地推广)。


一个有趣的方法。现在稍晚一点,您是否有生产经验? - Thorbjørn Ravn Andersen
3
@ThorbjørnRavnAndersen 在therapi-json-rpc项目中一直运作良好。至于吸取的教训,0.4.0版本将Javadoc存储在JSON类路径资源中,而不是生成的Java类中。这样可以生成更小的JAR文件,并且对类加载器更友好。注解处理器和运行时库现在是独立的组件,以提供更大的灵活性。这是我热衷的一个项目,我会尽快回应问题 - dnault
1
嗨@dnault,使用这种方法也可以访问javadoc警告和错误吗?例如,链接到另一个类,但有拼写错误。IDE会突出显示这样的内容,但我还没有找到通过AbstractProcessor和visitors/scanners访问它的方法。我正在使用此指南/示例:https://alvinalexander.com/java/jwarehouse/openjdk-8/langtools/test/tools/javac/diags/DocCommentProcessor.java.shtml - Hervian
@Hervian 我不认为这会对你有所帮助。如果你发现了一种可移植的方式来访问导入项以便验证链接,我很乐意听听你的想法 :-) - dnault

14
你不能:这个class文件中不包含注释。
“解决方案”是在构建程序时将javadoc生成为HTML,并根据类名和方法名构建URL。你也可以使用doclet API以更适合的格式生成javadoc。

这里提供了一个很好的“如何”使用doclet API:https://dev59.com/questions/_Woy5IYBdhLWcg3wguSS#12872074 - Thomas Jung
看看 Abhi 提供的自定义注释答案。它提供了一种不需要互联网的更简单的方法。 - Johannes
@Johannes 除了Abhi没有回答问题,问题是关于javadoc的,而不是类的其他部分... - Denys Séguret

4
你可以通过程序方式运行javadoc并传递选项,以生成所需类的文档,然后解析生成的文档以获取所需方法的文档。因为注释不在类文件中,所以你需要在运行时拥有源代码。

很难找到这个命令行,甚至在应用程序内部运行也是如此 :/ - Aquarius Power

3

注释在字节码中没有表示,编译器会将其剥离并在运行时不可用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接