从重复劳动到智能助手:我为什么要开发一个 JavaDoc 插件

random-pic-api

写在前面

作为一个程序员,我相信你一定也经历过这样的场景:刚写完一个复杂的业务方法,满心欢喜地准备提交代码,却被 CI/CD 检查卡住——“缺少 JavaDoc 注释”
。于是你不得不回到代码里,机械地补充那些看起来千篇一律的文档。

程序员写代码的日常

这不仅仅是我的痛点,我相信这也是每个追求代码质量的开发者共同的烦恼。今天,我想和大家分享我是如何从一个实际的问题出发,最终开发出了一款能够自动生成高质量
JavaDoc 的 IntelliJ IDEA 插件的故事。

痛点的诞生

那个让人崩溃的下午

记得那是一个普通的周二下午,我正在处理一个紧急的项目迭代。代码写得飞起,功能实现得顺风顺水,直到最后提交代码时,CI/CD 系统无情地拒绝了:

1
2
3
[ERROR] Missing JavaDoc for method 'calculateUserScore' in class 'UserService'
[ERROR] Missing JavaDoc for class 'OrderProcessor'
[ERROR] 3 more files missing JavaDoc documentation

看着屏幕上的错误信息,我陷入了沉思。这已经是我这个月第三次因为缺少 JavaDoc 而被迫返回去补充文档了。更让人沮丧的是,我发现自己在写 JavaDoc
的时候,基本上是在重复思考:

  • 这个方法是做什么的?(刚刚写完逻辑,当然知道)
  • 参数是什么意思?(参数名已经很清楚了)
  • 返回值是什么?(看代码就知道了)
  • 可能抛出什么异常?(大部分情况下都是标准异常)

写 JavaDoc 的痛苦

现有解决方案的不足

我开始尝试寻找解决方案。市面上确实有一些自动生成 JavaDoc 的工具,但它们都有各种问题:

  1. 模板化生成:大部分工具只是简单地基于方法签名生成模板,内容空洞,没有实际意义
  2. 理解能力有限:无法理解代码的业务逻辑,生成的文档往往不准确
  3. 格式死板:生成的文档千篇一律,缺乏个性化和上下文信息
  4. 集成度低:需要切换工具或者使用命令行,打断了开发流程

更糟糕的是,有些工具生成的 JavaDoc 比不写还要糟糕——它们会在文档里写着明显的废话:

1
2
3
4
5
6
7
8
/**
* This method calculates the user score.
* @param userId the user id
* @return the user score
*/
public int calculateUserScore(String userId) {
// ...
}

这种文档除了占用代码行数,没有任何实际价值。

灵感的闪现:AI 时代的解决方案

一次偶然的尝试

就在我对这些工具感到绝望的时候,我正在使用 ChatGPT 帮我解决一个算法问题。让我惊讶的是,当我把一个复杂的方法贴给 AI
时,它不仅理解了代码的逻辑,还能用通俗易懂的语言解释它的功能。

那一刻,我脑子里闪过一个念头:如果我能把 AI 的理解能力整合到 IDE 里,不就能解决 JavaDoc 的问题了吗?

AI 理解代码的启示

我开始思考这个问题:

  • AI 能够理解代码的逻辑和业务含义
  • AI 能够生成符合上下文的自然语言描述
  • AI 能够根据代码结构生成规范的 JavaDoc 格式
  • AI 能够处理各种编程语言和框架

这完美地解决了传统工具的所有痛点!

从想法到现实

兴奋之余,我开始调研实现的可能性:

  1. IntelliJ IDEA 插件开发:作为一个长期使用 IntelliJ IDEA 的开发者,我知道它有强大的插件生态
  2. AI 服务集成:现在有很多成熟的 AI 服务 API,可以直接调用
  3. 开发可行性:我之前有过一些插件开发经验,技术上应该是可行的

但是,当我真正开始着手的时候,发现事情并没有那么简单…

技术挑战与解决方案

第一个挑战:如何理解代码结构?

IntelliJ IDEA 插件开发最核心的就是要理解 IDE 的 PSI (Program Structure Interface) 机制。PSI 是 IntelliJ IDEA 用来表示代码结构的抽象语法树。

PSI 代码结构分析

1
2
3
4
5
6
7
8
9
10
11
12
13
// 需要理解这样的代码结构
public class UserService {
/**
* 根据用户ID获取用户信息,包含用户的积分、等级等详细信息
*
* @param userId 用户唯一标识,格式为 "user_" + 数字
* @return 用户详细信息,如果不存在返回 null
* @throws IllegalArgumentException 如果 userId 格式不正确
*/
public UserDTO getUserDetail(String userId) {
// 复杂的业务逻辑...
}
}

我需要能够:

  • 识别这是一个类定义
  • 解析方法的签名信息(名称、参数、返回值)
  • 提取方法的实现逻辑
  • 理解可能抛出的异常

第二个挑战:如何与 AI 服务集成?

现在 AI 服务很多,但如何选择和集成呢?我调研了市面上主要的 AI 服务:

服务商优势劣势
OpenAI理解能力强,支持中文成本较高,有网络限制
Anthropic逻辑推理强中文支持一般
Ollama本地部署,隐私保护好配置复杂
ModelScope中文优化好生态相对新

我决定不局限于某一个服务商,而是设计一个灵活的架构,支持多个 AI 服务商,用户可以根据自己的需求选择。

第三个挑战:如何提供良好的用户体验?

一个插件的好坏,很大程度上取决于用户体验。我希望用户能够:

  1. 多种触发方式:快捷键、右键菜单、Intention Action 等
  2. 实时反馈:生成过程中显示进度,避免用户焦虑
  3. 配置灵活:支持自定义 Prompt 模板、JavaDoc 标签等
  4. 性能优化:支持批量处理,减少等待时间

插件架构设计

整体架构

基于以上的分析,我设计了如下的插件架构:

插件架构图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌─────────────────────────────────────────────────────────────┐
│ IntelliJ IDEA │
├─────────────────────────────────────────────────────────────┤
│ Actions (多种触发方式) │
│ ├── Intention Action (Alt+Enter) │
│ ├── Shortcut (Cmd+Shift+D) │
│ ├── Editor Context Menu │
│ ├── Project View Menu │
│ └── Generate Menu (Cmd+N) │
├─────────────────────────────────────────────────────────────┤
│ Core Components (核心组件) │
│ ├── Settings & Configuration │
│ ├── Task Collector & Executor │
│ ├── AI Integration Layer │
│ └── UI Components (Console, StatusBar) │
├─────────────────────────────────────────────────────────────┤
│ IntelliAI Engine (AI 引擎) │
│ ├── AI Provider Manager │
│ ├── OpenAI, Anthropic, Ollama, ModelScope │
│ └── Streaming Response Handler │
└─────────────────────────────────────────────────────────────┘

核心组件详解

1. Actions - 多种触发方式

我设计了 5 种不同的触发方式,满足不同场景的需求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Intention Action - 最自然的触发方式
public class GenerateJavaDocIntentionAction {
// 当用户按下 Alt+Enter 时显示在提示列表中
}

// 快捷键 - 最高效的触发方式
public class GenerateJavaDocShortcutAction {
// 全局快捷键 Cmd+Shift+D
}

// 编辑器右键菜单
public class GenerateJavaDocForEditorAction {
// 在编辑器右键菜单中显示
}

2. Task System - 智能任务处理

这是插件的核心,负责识别需要生成文档的代码元素,并调用 AI 服务生成文档:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class TaskCollector {
public List<DocumentationTask> collectTasks(PsiElement element) {
// 智能识别类、方法、字段等元素
// 分析代码上下文
// 生成任务队列
}
}

public class TaskExecutor {
public void executeTasks(List<DocumentationTask> tasks) {
// 调用 AI 服务生成文档
// 处理流式响应
// 应用到代码中
}
}

3. AI Integration - 灵活的 AI 集成

为了支持多个 AI 服务商,我设计了统一的 AI 接口:

1
2
3
4
5
public interface AIProvider {
CompletableFuture<String> generateJavaDoc(CodeContext context, PromptTemplate template);
boolean supportsStreaming();
ProviderConfig getDefaultConfig();
}

4. Settings & Configuration - 丰富的配置选项

用户可以在设置页面配置各种选项:

设置界面截图

  • AI 提供商选择:支持多个服务商,可配置优先级
  • 元素类型选择:可选择为类、方法、字段生成文档
  • Prompt 模板:自定义生成文档的提示词
  • JavaDoc 标签:自定义支持的标签(如 @author、@date 等)
  • 性能模式:启用多服务商并行处理

功能详解

1. 智能识别,一键生成

插件能够智能识别光标位置的代码元素,自动选择合适的生成策略:

类级别的 JavaDoc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 生成前
public class UserService {
// ...
}

// 生成后
/**
* 用户服务核心业务类
*
* <p>提供用户相关的核心业务功能,包括用户注册、登录、信息查询、积分管理等。
* 该服务采用 Spring 框架实现,集成了缓存机制以保证性能。
*
* <p>主要功能:
* <ul>
* <li>用户注册和登录验证</li>
* <li>用户信息查询和更新</li>
* <li>用户积分计算和等级管理</li>
* <li>用户权限控制</li>
* </ul>
*
* @author dong4j
* @version 1.0.0
* @since 1.0.0
*/
public class UserService {
// ...
}

方法级别的 JavaDoc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 生成前
public UserDTO getUserDetail(String userId) {
// 复杂的业务逻辑...
}

// 生成后
/**
* 根据用户ID获取用户详细信息
*
* <p>通过用户ID查询用户的完整信息,包括基本资料、积分等级、权限状态等。
* 该方法会先查询缓存,如果缓存不存在则从数据库查询并更新缓存。
*
* @param userId 用户唯一标识,格式为 "user_" + 数字,不能为空
* @return 用户详细信息对象,包含用户的所有相关信息,如果用户不存在则返回 null
* @throws IllegalArgumentException 当 userId 格式不正确或为空时抛出
* @throws ServiceException 当查询数据库出现异常时抛出
*/
public UserDTO getUserDetail(String userId) {
// 复杂的业务逻辑...
}

2. 多种触发方式,适应不同习惯

每个开发者的使用习惯都不同,所以我提供了多种触发方式:

🎯 Intention Action (Alt+Enter)

这是最自然的方式,当你把光标放在某个类或方法上时,按下 Alt+Enter,插件会自动识别并提供生成 JavaDoc 的选项。

Intention Action 演示

⌨️ 快捷键 (Cmd+Shift+D)

对于喜欢键盘操作的开发者,全局快捷键是最快的方式。无论你在编辑器的哪个位置,都可以快速触发。

🖱️ 右键菜单

传统的右键菜单方式,适合不常用快捷键的用户。在编辑器和项目视图中都有对应的菜单项。

📋 Generate Menu (Cmd+N)

与 IntelliJ IDEA 的生成菜单集成,保持与 IDE 的一致性体验。

🔗 Git 集成

在 Git 提交页面,如果发现缺少 JavaDoc,可以直接点击按钮快速生成,避免切换上下文。

3. 智能配置,个性化定制

插件提供了丰富的配置选项,让每个开发者都能根据自己的需求进行调整。

AI 提供商配置

支持多个 AI 服务商,你可以:

  • 配置多个服务商的 API Key
  • 设置服务商优先级
  • 启用性能模式(多服务商并行)
  • 切换不同的模型(GPT-4、Claude-3 等)

AI 配置界面

Prompt 模板自定义

不同的团队有不同的文档风格要求,插件支持自定义 Prompt 模板:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 方法级别的 Prompt 模板示例
public String getMethodPromptTemplate() {
return """
请为以下 Java 方法生成详细的 JavaDoc 注释。

要求:
1. 方法描述要清晰说明方法的功能和用途
2. 参数说明要详细,包括格式要求、限制条件等
3. 返回值说明要具体,说明可能的返回情况
4. 异常说明要准确,列出所有可能抛出的异常
5. 使用中文描述,保持专业但易懂的语气
6. 如果方法有特殊的使用场景或注意事项,也要说明

代码:
{code}
""";
}

自定义 JavaDoc 标签

很多团队有自己的文档规范,插件支持自定义 JavaDoc 标签:

1
2
3
4
5
6
7
// 支持的标签配置
public class CustomJavaDocTagConfig {
private boolean enabled = true;
private String tagName = "@author";
private String description = "作者信息";
private String defaultValue = "dong4j";
}

4. 性能优化,提升效率

批量处理支持

当你需要为整个项目生成 JavaDoc 时,性能就很重要了。插件支持批量处理:

1
2
3
4
5
6
7
8
public class BatchProcessor {
public void processBatch(List<PsiFile> files) {
// 分析文件依赖关系
// 构建任务图
// 并行执行任务
// 实时显示进度
}
}

智能代码压缩

为了减少 AI 请求的 token 消耗,插件会智能压缩代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 原始代码
public class VeryLongClassNameWithLotsOfDetails {
public void veryLongMethodNameWithLotsOfParameters(
String veryLongParameterName1,
String veryLongParameterName2,
String veryLongParameterName3) {
// 大量实现代码...
}
}

// 压缩后发送给 AI
public class C {
public void m(String p1, String p2, String p3) {
// 核心逻辑保留...
}
}

性能模式

如果你配置了多个 AI 服务商,可以启用性能模式,让多个服务商并行处理不同的任务:

性能模式示意图

1
2
3
4
5
6
7
public class PerformanceModeExecutor {
public void executeInParallel(List<DocumentationTask> tasks) {
// 将任务分配给不同的 AI 服务商
// 并行执行,大幅提升处理速度
// 汇总结果,显示统计信息
}
}

开发过程中的坑与解决方案

坑1:PSI 事件处理

刚开始开发时,我遇到了一个棘手的问题:当生成 JavaDoc 后,如何正确处理 PSI 事件,避免重复处理?

1
2
3
4
5
6
7
8
9
10
11
12
// 错误的做法
public class BadJavaDocGenerator {
public void generateJavaDoc(PsiMethod method) {
// 生成 JavaDoc
String javadoc = generateContent(method);

// 直接修改 PSI
method.getDocComment().replace(createDocComment(javadoc));

// 这会触发 PSI 事件,可能导致循环处理!
}
}

解决方案:使用 PSI 事务和标记机制:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class GoodJavaDocGenerator {
public void generateJavaDoc(PsiMethod method) {
// 使用 WriteCommandAction 确保线程安全
WriteCommandAction.runWriteCommandAction(project, () -> {
// 添加标记,避免重复处理
boolean wasProcessing = isProcessing.setIfAbsent(true);
if (wasProcessing) {
return;
}

try {
String javadoc = generateContent(method);
PsiDocComment comment = createDocComment(javadoc);

// 使用正确的 PSI 修改 API
method.getDocComment().replace(comment);
} finally {
isProcessing.remove();
}
});
}
}

坑2:流式响应处理

AI 服务的流式响应处理起来很复杂,特别是在 IntelliJ IDEA 的 UI 线程中:

1
2
3
4
5
6
7
// 错误的做法:在 UI 线程中处理流式响应
public class BadStreamingHandler {
public void handleStreamingResponse(String response) {
// 直接更新 UI,可能导致界面卡顿
updateUI(response);
}
}

解决方案:使用异步处理和批更新:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class GoodStreamingHandler {
private final StringBuilder buffer = new StringBuilder();
private final ScheduledExecutorService scheduler;

public void handleStreamingResponse(String chunk) {
// 在后台线程处理
buffer.append(chunk);

// 延迟更新 UI,避免频繁刷新
scheduler.schedule(this::updateUIIfNeeded, 100, TimeUnit.MILLISECONDS);
}

private void updateUIIfNeeded() {
if (buffer.length() > 0) {
ApplicationManager.getApplication().invokeLater(() -> {
// 在 UI 线程更新
updateUI(buffer.toString());
buffer.setLength(0);
});
}
}
}

坑3:配置持久化

IntelliJ IDEA 的配置持久化机制虽然强大,但是有很多细节需要注意:

1
2
3
4
5
6
7
8
9
// 错误的配置类定义
@State(name = "BadConfig", storages = @Storage("bad_config.xml"))
public class BadConfig {
public String apiKey; // 不会自动持久化

public void setApiKey(String apiKey) {
this.apiKey = apiKey; // 需要手动触发保存
}
}

解决方案:正确使用 PersistentStateComponent:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@State(name = "JavaDocAISettings",
storages = @Storage("zeka.stack.intelliai.javadoc.xml"))
public class SettingsState implements PersistentStateComponent<SettingsState> {
public AIProviderConfig providerConfig = new AIProviderConfig();
public Set<String> supportedLanguages = new HashSet<>();

@Nullable
@Override
public SettingsState getState() {
return this;
}

@Override
public void loadState(@NotNull SettingsState state) {
XmlSerializerUtil.copyBean(state, this);
}
}

使用体验和效果

真实场景测试

让我用几个真实的场景来展示插件的效果:

场景1:重构遗留代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 重构前:一个没有任何文档的复杂方法
public List<OrderDTO> getOrders(String userId, String status, Date start, Date end) {
List<Order> orders = orderMapper.findByUserIdAndStatusAndCreateTimeBetween(userId, status, start, end);
return orders.stream().map(this::convertToDTO).collect(Collectors.toList());
}

// 使用插件生成后
/**
* 根据用户ID、订单状态和时间范围查询订单列表
*
* <p>查询指定用户在给定时间范围内的订单信息,支持按状态筛选。
* 该方法会调用数据库查询,然后将订单实体转换为 DTO 对象返回。
* 主要用于订单列表展示和订单管理功能。
*
* @param userId 用户唯一标识,不能为空
* @param status 订单状态筛选条件,可选值:PENDING, PROCESSING, COMPLETED, CANCELLED,可为空表示查询所有状态
* @param start 开始时间,查询范围的起始时间,不能为空
* @param end 结束时间,查询范围的结束时间,不能为空
* @return 订单信息列表,包含订单的基本信息、商品信息、支付状态等,如果无匹配订单则返回空列表
* @throws IllegalArgumentException 当 userId、start、end 为空时抛出
* @throws ServiceException 当数据库查询出现异常时抛出
*/
public List<OrderDTO> getOrders(String userId, String status, Date start, Date end) {
List<Order> orders = orderMapper.findByUserIdAndStatusAndCreateTimeBetween(userId, status, start, end);
return orders.stream().map(this::convertToDTO).collect(Collectors.toList());
}

场景2:新功能开发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 开发新功能时快速生成文档
/**
* 用户积分计算服务类
*
* <p>提供用户积分计算相关的核心功能,包括积分获取、消费计算、等级评定等。
* 该服务整合了多种积分来源(购物、签到、分享等),支持复杂的积分规则配置。
*
* @author dong4j
* @version 1.0.0
* @since 1.0.0
*/
@Service
public class UserScoreService {

/**
* 计算用户的总积分
*
* <p>汇总用户所有类型的积分,包括可用积分、冻结积分、历史积分等。
* 该方法会实时查询数据库,确保积分信息的准确性。
*
* @param userId 用户唯一标识,不能为空
* @return 用户积分信息,包含总积分、可用积分、冻结积分等详细信息
* @throws IllegalArgumentException 当 userId 为空时抛出
* @throws ServiceException 当查询过程中出现异常时抛出
*/
public UserScoreInfo calculateTotalScore(String userId) {
// 实现逻辑...
}
}

效率提升统计

使用插件后,我在文档编写上的效率有了显著提升:

任务类型手动编写耗时插件生成耗时效率提升
简单方法 JavaDoc3-5 分钟10-20 秒约 10x
复杂方法 JavaDoc10-15 分钟30-60 秒约 12x
类级别 JavaDoc20-30 分钟1-2 分钟约 15x
批量处理 50 个文件2-3 小时10-15 分钟约 12x

更重要的是,生成的文档质量往往比我手动写的还要好,因为 AI 能够:

  • 更全面地考虑各种边界情况
  • 更准确地描述复杂的业务逻辑
  • 保持文档风格的一致性

团队使用反馈

我把插件推荐给了团队的几个同事,他们的反馈也很积极:

“这个插件太强了!再也不用为了写文档而纠结了,生成的文档质量很高,基本上不用修改。” —— 前端开发同事

“最让我惊喜的是它能够理解我们项目的业务逻辑,生成的文档很专业,不像其他工具那样千篇一律。” —— 后端开发同事

“配置很灵活,我们团队可以根据自己的文档规范进行定制,这点做得很好。” —— 架构师同事

未来规划

虽然插件现在已经很好用了,但我还有很多改进计划:

近期计划

  1. 多语言支持

    • 目前主要支持 Java,未来会扩展到 Kotlin、Python、JavaScript 等语言
    • 每种语言都会有专门的解析和生成策略
  2. 团队协作功能

    • 共享配置模板
    • 统一的文档规范管理
    • 团队使用统计
  3. 更智能的文档管理

    • 文档更新提醒
    • 过时文档检测
    • 文档质量评分

长期规划

  1. 代码语义理解增强

    • 结合项目的业务领域知识
    • 学习团队的编码风格
    • 生成更具上下文的文档
  2. 全生命周期文档管理

    • 需求文档 → 代码 → 文档 → 测试用例的全链路打通
    • 文档版本管理
    • 文档变更追踪
  3. IDE 集成增强

    • 更多 IDE 支持(VS Code、Eclipse)
    • 云端 IDE 集成
    • 移动端文档查看

开源与社区

这个项目已经开源在 GitHub 上,我希望能有更多的开发者参与进来:

为什么选择开源?

  1. 回馈社区:我从开源社区中学到了很多,现在是时候回馈了
  2. 质量提升:更多的代码审查和测试,让插件更加稳定
  3. 功能完善:社区的贡献能让插件支持更多场景和语言
  4. 标准化:推动 JavaDoc 生成工具的标准化

如何参与?

  1. 使用和反馈:安装使用插件,提出使用体验和建议
  2. 代码贡献:修复 bug、添加新功能、完善文档
  3. 测试支持:在不同环境下测试,确保兼容性
  4. 推广分享:推荐给其他可能需要的开发者

贡献指南

我制定了详细的贡献指南,包括:

  • 开发环境搭建
  • 代码规范要求
  • 测试编写指南
  • Pull Request 流程
  • Issue 报告模板

总结与感悟

开发这个插件的过程,让我收获了很多:

技术层面的成长

  1. IntelliJ IDEA 插件开发:深入了解了 IntelliJ IDEA 的插件体系、PSI 机制、UI 组件等
  2. AI 服务集成:学会了如何与多个 AI 服务商集成,处理流式响应,优化性能
  3. 软件架构设计:从单机工具到插件化架构,再到微服务化的演进
  4. 用户体验优化:学习了如何设计符合用户习惯的交互方式

思考方式的转变

  1. 从问题到解决方案:不再是简单地接受问题,而是深入思考如何从根本上解决问题
  2. 从功能到体验:不仅关注功能的实现,更注重用户的使用体验
  3. 从个人到团队:考虑的不再只是个人的需求,而是团队和社区的共同需求
  4. 从工具到平台:把一个简单的工具,逐步打造成一个可扩展的平台

对软件开发的思考

  1. 工具的重要性:好的工具能够极大地提升开发效率和质量
  2. AI 的价值:AI 不是要取代开发者,而是要成为开发者的智能助手
  3. 开源的力量:开源不仅仅是代码共享,更是一种协作和学习的文化
  4. 持续改进:软件开发没有终点,只有不断迭代和优化

致谢

最后,我要感谢所有帮助我完成这个项目的人和工具:

特别感谢

  • IntelliJ IDEA 团队:感谢他们提供了如此强大的 IDE 和插件开发平台
  • OpenAI、Anthropic 等服务商:感谢他们提供了强大的 AI 服务能力
  • 开源社区:感谢所有开源项目的贡献者,让我学到了很多

工具感谢

  • IntelliJ IDEA:最好的 Java IDE,没有之一
  • Git:版本控制的神器
  • Gradle:强大的构建工具
  • GitHub:代码托管和协作平台

相关链接

插件地址

相关项目

个人链接

参考资源


如果你觉得这个插件对你有帮助,欢迎在 GitHub 上点个 Star,或者推荐给其他可能需要的朋友。如果你在使用过程中遇到任何问题,也欢迎提 Issue
或者直接联系我。让我们一起,用 AI 的力量,让编程变得更加高效和有趣!
🚀