java-docs
Installation
SKILL.md
Java Docs
目标
为 Java 声明生成可审阅、可维护、语义正确的中文 Javadoc。
交付时保持以下原则:
- 只修改 Javadoc 或与 Javadoc 直接相关的空白格式。
- 不改业务逻辑、不改命名、不重排无关注释。
- 默认输出最小改动,便于直接审阅和应用。
适用范围
本技能适用于以下声明:
- 类
class - 接口
interface - 注解类型
@interface - 枚举
enum - 枚举常量
- 记录
record - record 组件
- 紧凑构造器
- 构造器
- 方法
- 泛型类型参数
<T> - 字段
工作流
- 先识别声明类型、签名、参数、返回值、异常列表。
- 判断是补全注释、修复注释,还是统一标签顺序。
- 按本技能内的规则生成或修复 Javadoc。
- 在输出前做一次自检,确认标签与签名完全一致,尤其不要为未声明
throws的签名补@throws。
修复优先级
按以下优先级决策,优先最小改动,只有在原注释明显不可用时才整段重写。
什么时候只补缺失标签
满足以下条件时,只补缺失标签或做最小调整:
- 原有说明文本是中文,且语义基本正确。
- 原有说明与当前声明用途一致,没有明显串行、复制错位或过期描述。
- 只是缺少
@param、@return、@since或缺少个别@throws。 - 标签顺序有问题,但标签内容本身仍然可用。
- 参数名、返回值、异常列表与签名大体一致,只需要补齐或轻微修正。
此时应尽量保留原描述,只补标签、修正顺序、修正个别名称,不要整段改写。
什么时候整段重写注释
满足以下任一情况时,直接整段重写当前 Javadoc:
- 完全没有 Javadoc。
- 原注释不是中文,且项目没有明确要求保留原语言。
- 原说明与声明语义明显不符,例如复制了别的方法、别的类的描述。
- 标签大面积错误,例如参数顺序全错、
void方法写了@return、未声明throws却写了多个@throws。 - 原注释过于空泛,无法支撑审阅,例如只有“测试方法”“处理数据”“TODO”等无效描述。
- 原注释结构混乱,局部修补后仍然不如重写更清晰。
整段重写时,保留业务代码和无关注释不动,只替换当前声明对应的 Javadoc 块。
什么时候保留原有描述不动
满足以下条件时,保留原有说明文本不动,只做必要的结构修复:
- 原说明已经准确表达该声明职责。
- 原说明使用了项目内特有术语、领域词或团队约定表达。
- 原说明文字质量可接受,没有明显歧义或过时信息。
- 当前问题仅在标签缺失、标签顺序、空白格式或少量签名对齐。
此时不要为了“统一文风”重写原描述,更不要把已有业务术语替换成泛化表述。
全局规则
- 注释说明文本使用中文简体。
- 标识符、类型名、包名、类名保持代码原文,不翻译。
- 注释格式必须使用标准
/** ... */。 - 缩进与周围代码风格保持一致。
@since必须使用版本语义,例如1.0.0,不要写日期。- 泛型类型参数使用
@param <T>形式,顺序与声明中的类型参数顺序一致。 @param顺序必须与方法或构造器签名完全一致。void方法不能写@return。- 非
void方法必须写@return。 - 只有方法或构造器签名中显式声明了
throws,才写@throws。 - 没有显式
throws时,即使方法体内抛出了IllegalArgumentException、IllegalStateException等运行时异常,也不要写@throws。 - 注解类型本身按普通类型处理;注解成员按无参方法处理,通常补
@return。 - 枚举常量如果承载明确业务语义,默认逐个补用途说明,并在同一个枚举内保持风格一致。
- record 组件优先在 record 类型 Javadoc 中使用
@param描述,顺序与组件声明一致。 - 紧凑构造器如果包含校验、归一化或复制逻辑,应补构造器 Javadoc,并沿用 record 组件名作为
@param名称。 - 带复杂泛型的参数和返回值优先使用
{@code ...},例如{@code Map<String, List<Long>>}、{@code T}。 - 禁止使用
{@inheritDoc}。重写方法必须写完整中文 Javadoc;若行为与父类基本一致,也要用中文重新说明。 - 字段注释只描述字段用途,不要写
@param、@return、@throws。
基础设施字段策略
以下字段按固定策略处理,避免无意义地补注释:
serialVersionUID:默认补简短字段注释,使用“序列化版本号。”- 日志字段,如
log、logger、LOGGER:默认不强制补 Javadoc,除非用户明确要求字段全部补齐。 - 依赖注入字段,如
repository、mapper、client、service:默认不强制补 Javadoc,除非字段名不足以表达用途或同类型依赖较多。 - 常量字段:业务语义不直观时补字段用途说明;字面量含义已经极清晰且你不需要全字段注释时,可以省略。
- 编译器生成、框架约定或明显样板化的基础设施字段,不要为了凑齐格式强行生成长注释。
标签顺序
按声明类型使用固定顺序:
- 普通类型 / 接口 / 枚举 / 注解类型:
@author->@since->@deprecated - 泛型类型声明:
@param <T>->@author->@since->@deprecated - record 类型声明:组件
@param->@author->@since->@deprecated - 构造器:
@param->@throws->@deprecated - 普通方法:
@param->@return->@throws->@deprecated - 泛型方法:
@param <T>->@param->@return->@throws->@deprecated - 字段:
@deprecated
@deprecated 规则
- 只有声明本身已经存在
@Deprecated,或用户明确要求标记弃用时,才新增@deprecated。 @deprecated必须写明弃用原因,以及替代方案或迁移路径。- 替代方案可以明确指向具体 API 时,优先使用
{@link ...}。 - 不使用
@see标签;如需说明替代 API,直接在@deprecated文本中写清楚。
类型标注规则
在 @param 和 @return 描述中,类型标注遵循以下约定:
- 基本类型:转成包装类型后使用
{@link ...} - 简单引用类型:使用
{@link ...} - 自定义对象:使用
{@link ...} - 类型变量:使用
{@code ...},例如{@code T} - 泛型、集合、映射、Optional、嵌套泛型:使用
{@code ...} - 数组、可变参数:使用
{@code ...}
基本类型映射:
byte -> Byteshort -> Shortint -> Integerlong -> Longfloat -> Floatdouble -> Doublechar -> Characterboolean -> Boolean
模板
类型
/**
* 类型功能描述。
*
* @author dev@example.com(Dev)
* @since 1.0.0
*/
public class Example {
}
接口
/**
* 订单查询接口。
*
* @author dev@example.com(Dev)
* @since 1.0.0
*/
public interface OrderQueryService {
/**
* 根据订单编号查询订单标题。
*
* @param orderId {@link Long} 订单编号
* @return {@link String} 订单标题
*/
String findTitle(Long orderId);
/**
* 根据订单编号加载订单详情。
*
* @param orderId {@link Long} 订单编号
* @return {@link String} 订单详情内容
* @throws IOException 读取订单详情失败时抛出
*/
String loadDetail(Long orderId) throws IOException;
}
注解类型
/**
* 内部使用标记注解。
*
* @author dev@example.com(Dev)
* @since 1.0.0
*/
public @interface InternalMarker {
/**
* 获取标记值。
*
* @return {@link String} 标记内容
*/
String value();
}
泛型类型
/**
* 缓存条目。
*
* @param <T> 缓存值类型
* @author dev@example.com(Dev)
* @since 1.0.0
*/
public class CacheEntry<T> {
/**
* 缓存值。
*/
private final T value;
/**
* 使用缓存值创建条目。
*
* @param value {@code T} 缓存值
*/
public CacheEntry(T value) {
this.value = value;
}
/**
* 获取缓存值。
*
* @return {@code T} 缓存值
*/
public T getValue() {
return value;
}
}
枚举
/**
* 订单状态枚举。
*
* @author dev@example.com(Dev)
* @since 1.0.0
*/
public enum OrderStatus {
/**
* 已创建。
*/
CREATED,
/**
* 已支付。
*/
PAID,
/**
* 已关闭。
*/
CLOSED
}
记录
/**
* 订单摘要记录。
*
* @param orderNo {@link String} 订单编号
* @param amount {@link BigDecimal} 订单金额
* @author dev@example.com(Dev)
* @since 1.0.0
*/
public record OrderSummary(
String orderNo,
BigDecimal amount
) {
/**
* 创建订单摘要记录。
*
* @param orderNo {@link String} 订单编号
* @param amount {@link BigDecimal} 订单金额
*/
public OrderSummary {
}
}
构造器
/**
* 构造器功能描述。
*
* @param name {@link String} 名称
*/
public Example(String name) {
}
/**
* 构造器功能描述。
*
* @param name {@link String} 名称
* @throws IllegalArgumentException 参数非法时抛出
*/
public Example(String name) throws IllegalArgumentException {
}
方法
/**
* 方法功能描述。
*
* @param count {@link Integer} 数量
* @param names {@code List<String>} 名称列表
* @return {@link String} 返回结果
*/
public String run(int count, List<String> names) {
}
泛型方法
/**
* 转换输入数据。
*
* @param <T> 输入类型
* @param <R> 输出类型
* @param source {@code T} 原始数据
* @param mapper {@code Function<T, R>} 转换函数
* @return {@code R} 转换结果
*/
public <T, R> R transform(T source, Function<T, R> mapper) {
return mapper.apply(source);
}
带显式 throws 的接口方法
/**
* 加载远程统计结果。
*
* @param ids {@code List<String>} 标识列表
* @return {@code Map<String, List<Long>>} 按标识分组的统计结果
* @throws IOException 远程读取失败时抛出
*/
Map<String, List<Long>> loadStats(List<String> ids) throws IOException;
Deprecated 方法
/**
* 查询旧版订单编码。
*
* @param orderId {@link Long} 订单编号
* @return {@link String} 旧版订单编码
* @deprecated 该方法仅兼容旧流程,请改用 {@link #findOrderCode(Long)} 获取标准订单编码。
*/
public String loadLegacyCode(Long orderId) {
return "";
}
Getter/Setter
/**
* 获取服务名称。
*
* @return {@link String} 服务名称
*/
public String getServiceName() {
return serviceName;
}
/**
* 设置摘要能力是否启用。
*
* @param enabled {@link Boolean} 是否启用
*/
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
重写方法
/**
* 格式化输入内容并在外层增加方括号。
*
* @param input {@link String} 原始输入内容
* @return {@link String} 增强后的格式化结果
*/
@Override
public String format(String input) {
return "[" + input + "]";
}
字段
/**
* 字段用途说明。
*/
private String appName;
输出方式
默认使用 patch 风格输出,只给出最小改动片段。
按用户要求切换:
- 用户明确要完整文件时,输出完整文件。
- 用户只给出单个声明时,输出该声明片段。
- 用户没有特别要求时,不要输出长篇解释。
patch 输出时,优先直接给出可替换代码片段,不要额外包裹“说明”“分析”“原因”等长文本。
full-file 输出时,返回完整文件内容,不使用 diff 标记,不额外解释。
snippet 输出时,只返回目标声明及其 Javadoc,不附带类外无关上下文。
Patch 示例 1:为缺失注释的方法补全 Javadoc
输入代码:
public String buildMessage(int count, List<String> tags) {
return count + ":" + tags;
}
期望输出:
/**
* 构建消息内容。
*
* @param count {@link Integer} 数量
* @param tags {@code List<String>} 标签列表
* @return {@link String} 生成的消息内容
*/
public String buildMessage(int count, List<String> tags) {
return count + ":" + tags;
}
Patch 示例 2:修复错误的 @return 与多余的 @throws
输入代码:
/**
* 更新启用状态。
*
* @param enabled {@link Boolean} 是否启用
* @return {@link Boolean} 是否成功
* @throws IllegalArgumentException 参数非法时抛出
*/
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
期望输出:
/**
* 更新启用状态。
*
* @param enabled {@link Boolean} 是否启用
*/
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
Full-file 示例:用户要求返回完整文件
输入请求:
为 UserProfile.java 补全类注释和 getter 注释,并直接返回完整文件。
期望输出:
package com.example.demo;
/**
* 用户资料服务。
*
* @author dev@example.com(Dev)
* @since 1.0.0
*/
public class UserProfile {
/**
* 用户名称。
*/
private final String username;
/**
* 使用用户名创建资料对象。
*
* @param username {@link String} 用户名称
*/
public UserProfile(String username) {
this.username = username;
}
/**
* 获取用户名称。
*
* @return {@link String} 用户名称
*/
public String getUsername() {
return username;
}
}
Snippet 示例:用户只要单个声明片段
输入请求:
只给我 buildCode 方法的注释片段,不要输出完整文件。
期望输出:
/**
* 构建业务编码。
*
* @param prefix {@link String} 编码前缀
* @param number {@link Integer} 编号
* @return {@link String} 生成后的业务编码
*/
public String buildCode(String prefix, int number) {
return prefix + "-" + number;
}
自检清单
提交前逐项检查:
- 注释说明是否为中文。
@param名称和顺序是否与签名一致。void方法是否错误出现@return。- 非
void方法是否缺失@return。 - 只有显式声明了
throws的签名才出现@throws。 - 若签名声明了
throws,@throws是否覆盖这些显式声明异常。 @deprecated是否明确写出弃用原因和替代方案。@since是否为版本号格式。- 标签顺序是否正确。
- 基础设施字段是否按策略补齐或省略,而不是机械生成注释。
- 字段是否误用了方法标签。
- 是否只修改了与 Javadoc 相关的内容。
交付要求
- 优先给出可直接应用的结果。
- 不输出与请求无关的扩展建议,除非用户主动询问。
- 如果项目已有既定作者名、版本号格式或注释语气,优先沿用项目现状。