You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何扫描Java标准API Javadoc的@since标签及-release实现原理

构建Java标准API与引入版本的映射方案

基于@since标签的扫描实现

你要的类、方法、枚举值和首次引入Java版本的对应关系,最直接的数据源就是各版本JDK自带src.zip源码包中Javadoc的@since标记:

  • 比如java.lang.String类的注释上标有@since 1.0,String::strip()方法注释上标有@since 11,和实际版本情况完全对应。
  • 具体实现可以直接用JDK内置的Doclet API,或者引入javaparser这类源码解析库,遍历src.zip中所有公开API(排除sun.*、jdk.internal.*这类内部包下的非公开类),提取每个类、方法、字段、枚举值的签名和对应的@since值即可。
  • 注意不要只扫最新版JDK的源码:部分早期API在后续版本中会被移除,还有少量@since标记存在错标、漏标的情况,最好从Java 1.0到最新LTS版本逐版本交叉校验——如果一个方法在JDK 10的类中不存在、JDK 11中首次出现,哪怕注释漏标,也能准确判定它的引入版本是11。

javac -release参数的实现原理(无Javadoc依赖的实现参考)

你提到的Java 9+编译器-release参数的版本校验能力,完全不依赖src.zip,也不会扫描任何Javadoc内容,性能和准确性都远高于源码扫描方案:

  • JDK从9版本开始,在安装目录的lib路径下自带了一个ct.sym文件,这是官方预先生成的版本化API签名库。这个文件本质是个压缩包,里面按Java版本分目录存储了对应版本所有公开标准API的精简字节码:只保留类、方法、字段的签名信息,去掉了方法实现、注释、调试信息等所有冗余内容。
  • 当执行javac -release N命令编译时,编译器不会直接加载当前JDK运行时的类作为编译类路径,而是从ct.sym中取出版本N对应的API签名集合作为唯一的编译期类路径。如果代码中引用了不在这个签名集合里的类、方法或者字段,就会直接抛出"找不到符号"的编译错误——你举的-release 10下调用String::strip()报错的场景,就是因为Java 10对应的签名集合里根本没有strip()方法的签名,编译器直接就能识别出来,不需要解析任何注释。
  • 这套方案比扫Javadoc靠谱得多:一方面预生成的二进制签名加载校验速度极快,另一方面完全不会出现@since错标、漏标的问题,还能准确识别不同版本中被删除的API——比如JDK9移除了sun.misc.BASE64Encoder类,-release 8时能找到这个类的签名,-release 9时就找不到,这类信息是只扫最新版JDK的@since标签根本拿不到的。

无Javadoc依赖的映射构建方式

如果你不想解析Javadoc的@since标签,完全可以直接复用ct.sym这套官方数据源:

  • 直接解压读取各版本JDK自带的ct.sym文件,遍历每个版本目录下的精简class文件,提取所有类、方法、字段的签名,就能直接得到每个API的首次出现版本、以及后续被移除的版本,准确率比扫@since高很多。
  • 也可以直接调用JDK内置的jdeps模块API,批量校验指定API签名在不同Java版本下是否存在,不需要自己解析二进制格式。

内容的提问来源于stack exchange,提问作者Rostislav Krasny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 02:48:27