您的位置:首页 > 文旅 > 美景 > 管理咨询公司怎么样_重庆建筑工程职业学院_汉中seo培训_网站seo诊断分析报告

管理咨询公司怎么样_重庆建筑工程职业学院_汉中seo培训_网站seo诊断分析报告

2024/12/23 9:57:12 来源:https://blog.csdn.net/10km/article/details/142518564  浏览:    关键词:管理咨询公司怎么样_重庆建筑工程职业学院_汉中seo培训_网站seo诊断分析报告
管理咨询公司怎么样_重庆建筑工程职业学院_汉中seo培训_网站seo诊断分析报告

几年前写过一博客:《java:通过javadoc API读取java源码中的注释信息(comment)》,简单介绍了通过javadoc API读取源码注释的流程。
那时还是用JDK 1.8。但是在JDK9环境下JDK 1.8的那一套API就不能用了。JDK 9提供了一套新的javadoc API实现注释代码的读取,即jdk.javadoc 模块。
本文说明如何基于jdk.javadoc来读取源码的注释。

module-info.java

需要在你的项目module-info.java中如下添加jdk.javadoc引用。

module you_module_name{exports you.package.name;requires transitive  jdk.javadoc;
}

类型迁移

从JDK 1.8迁移到JDK 9是个挺麻烦的事儿,
下面列表出了JDK 1.8下javadoc API与JDK 9提供的类型对应表。

此表只能做为基本的参照,其实许多类型在没有完全等价的类型。

Old Type(JDK8)New Type(JDK9)
AnnotatedTypejavax.lang.model.type.TypeMirror
AnnotationDescjavax.lang.model.element.AnnotationMirror
AnnotationDesc.ElementValuePairjavax.lang.model.element.AnnotationValue
AnnotationTypeDocjavax.lang.model.element.TypeElement
AnnotationTypeElementDocjavax.lang.model.element.ExecutableElement
AnnotationValuejavax.lang.model.element.AnnotationValue
ClassDocjavax.lang.model.element.TypeElement
ConstructorDocjavax.lang.model.element.ExecutableElement
Docjavax.lang.model.element.Element
DocErrorReporterjdk.javadoc.doclet.Reporter
Docletjdk.javadoc.doclet.Doclet
ExecutableMemberDocjavax.lang.model.element.ExecutableElement
FieldDocjavax.lang.model.element.VariableElement
LanguageVersionjavax.lang.model.SourceVersion
MemberDocjavax.lang.model.element.Element
MethodDocjavax.lang.model.element.ExecutableElement
PackageDocjavax.lang.model.element.PackageElement
Parameterjavax.lang.model.element.VariableElement
ParameterizedTypejavax.lang.model.type.DeclaredType
ParamTagcom.sun.source.doctree.ParamTree
ProgramElementDocjavax.lang.model.element.Element
RootDocjdk.javadoc.doclet.DocletEnvironment
SeeTagcom.sun.source.doctree.LinkTree
com.sun.source.doctree.SeeTree
SerialFieldTagcom.sun.source.doctree.SerialFieldTree
SourcePositioncom.sun.source.util.SourcePositions
Tagcom.sun.source.doctree.DocTree
ThrowsTagcom.sun.source.doctree.ThrowsTree
Typejavax.lang.model.type.TypeMirror
TypeVariablejavax.lang.model.type.TypeVariable
WildcardTypejavax.lang.model.type.WildcardType

Doclet

JDK 1.8中Doclet的定义很随意,只要有一个start静态方法就可以了。如下:

	public static  class Doclet {public Doclet() {}public static boolean start(RootDoc root) {// 获取 javadoc根数据对象,从该根对象可以提取所有其他程序结构信息JavaDocReader.root = root;return true;}}

但JDK9中对doclet类型做接口化约束,要求doclet必须实现jdk.javadoc.doclet.Doclet接口,示例如下:

	public static class DocletExample implements jdk.javadoc.doclet.Doclet {private DocletEnvironment docEnv;@Overridepublic void init(Locale locale, Reporter reporter) {}@Overridepublic boolean run(DocletEnvironment docEnv) {// 表示单次调用doclet的操作环境。此对象可用于访问命令行上的程序结构、各种实用程序和用户指定的元素。// 对应与JDK 1.8下的RootDocthis.docEnv = docEnv;return true;}@Overridepublic String getName() {return "DocletExample";}@Overridepublic Set<? extends Option> getSupportedOptions() {return Set.of();}@Overridepublic SourceVersion getSupportedSourceVersion() {return SourceVersion.latest();}}

JavadocTool

JDK 1.8下程序执行javadoc直接调用com.sun.tools.javadoc.Main中的mainexecute静态方法。
在JDK 9下com.sun.tools.javadoc.Main已经不存在了。JDK 9对JDK 命令行工具进行了统一封装为ToolProvider接口,需要使用ToolProvider机制获取JavadocToolProvider执行javadoc.

/** 获取 javadoc tool */
ToolProvider javadocTool = ToolProvider.findFirst("javadoc").orElseThrow();
/** 执行javadoc */
javadocTool.run(System.out,System.err,new String[] {....});

实现代码

以下是基于jdk.javadoc实现的读取源码注释的示例代码,实现读取指定的包下的所有源码注释,并输出每个类及类成员的注解。

import org.junit.Test;
import static org.junit.Assert.*;import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.spi.ToolProvider;import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.Elements;
import javax.tools.Diagnostic.Kind;import com.sun.source.doctree.BlockTagTree;
import com.sun.source.doctree.DocCommentTree;
import com.sun.source.util.DocTrees;import jdk.javadoc.doclet.Doclet;
import jdk.javadoc.doclet.DocletEnvironment;
import jdk.javadoc.doclet.Reporter;/*** JDK 9的javadoc tool 调用测试* @author guyadong**/
public class JavadocToolTest {@Testpublic void testJavadocTool() {try {/** 获取 javadoc tool */ToolProvider javadocTool = ToolProvider.findFirst("javadoc").orElseThrow();int returnCode = javadocTool.run(System.out,System.err,new String[] {/** 指定自定义的  Doclet 接口实现类(全名)  */"-doclet", DocletExample.class.getName(), /** 指定-doclet选项定义类名的所在的类搜索路径  */"-docletpath", DocletExample.class.getProtectionDomain().getCodeSource().getLocation().getPath(),/** --subpackages 要获取注释的包名 */"-subpackages",	"net.gdface.utils",/** --sourcepath 要源码路径 */"-sourcepath","D:/j/common-java/common-base/src/main/java",/** --classpath 指定javadoc执行时搜索引用类的路径 */"-classpath","D:/j/common-java/common-base/target/classes","-encoding","utf-8"});if(0 != returnCode){System.out.printf("javadoc ERROR CODE = %d\n", returnCode);throw new IllegalStateException();}} catch (Throwable e) {e.printStackTrace();fail();}}public static class DocletExample implements Doclet {private Reporter reporter;private Elements elementUtils;@Overridepublic void init(Locale locale, Reporter reporter) {reporter.print(Kind.NOTE, "Doclet using locale: " + locale);this.reporter = reporter;}/** 输出类成员的注释 */ public void printElement(DocTrees trees, Element e) {DocCommentTree docCommentTree = trees.getDocCommentTree(e);if (docCommentTree != null) {reporter.print(Kind.NOTE, "Element " + e.getKind() + ": "+ e);// 输出对应的注解reporter.print(Kind.NOTE,elementUtils.getDocComment(e));}}@Overridepublic boolean run(DocletEnvironment docEnv) {// get the DocTrees utility class to access document commentsDocTrees docTrees = docEnv.getDocTrees();elementUtils = docEnv.getElementUtils();// 循环调用printElement输出每个类成员的注释for (TypeElement t : ElementFilter.typesIn(docEnv.getIncludedElements())) {reporter.print(Kind.NOTE, t.getKind() + ":" + t.getQualifiedName());reporter.print(Kind.NOTE, "getDocComment:"+elementUtils.getDocComment(t));	            for (Element e : t.getEnclosedElements()) {printElement(docTrees, e);}}return true;}@Overridepublic String getName() {return "DocletExample";}@Overridepublic Set<? extends Option> getSupportedOptions() {Option[] options = {};return Set.of(options);}@Overridepublic SourceVersion getSupportedSourceVersion() {// support the latest releasereturn SourceVersion.latest();}}
}

完整代码

完整代码参见码云仓库:https://gitee.com/l0km/javadocreader9

参考资料

《javadoc》
《Package jdk.javadoc.doclet》

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com