AI 辅助 Java 代码生成:从需求描述到可运行的 CRUD 代码
最近在 Java 项目里,我越来越多地把“写样板代码”的工作交给 AI:给它一段需求描述,让它先生成一版可运行的 CRUD 代码,我再逐行核对、补测试、接进工程。这样做不是为了省掉思考,而是把时间花在真正需要判断的地方——需求是否合理、边界是否处理、数据是否一致。
一、从一句话需求开始:先写清楚,再让 AI 写代码
AI 生成代码的质量,取决于需求描述的完整程度。一句“帮我写个任务管理接口”太笼统,生成结果往往缺字段、缺校验、缺异常处理。我现在写提示词时会固定包含五要素:业务对象和字段、要支持的操作、输入校验规则、异常与边界情况、技术约束。
比如这次的需求是这样写的:“实现一个任务(Task)管理功能,字段包括 id、标题、状态(TODO/DOING/DONE)、创建时间;支持新增、按 id 查询、查询全部、更新状态、删除;标题不能为空、长度不超过 100 个字符;不存在的 id 查询和更新要返回明确的错误提示;用纯 Java 实现,不依赖数据库和第三方框架,先跑通逻辑。”
需求写得越具体,AI 的发挥空间反而越可控:它不需要猜字段含义,也不需要猜你要不要持久化。
二、让 AI 生成第一版:分层结构一次给全
拿到需求后,我会请 AI 一次性给出分层清晰的完整代码,而不是一段段零散的片段。原因很简单:片段式生成容易出现命名不一致、方法签名对不上的问题,拼起来反而更费时间。第一版的验收标准只有三条:能编译、能跑通主流程、结构分层清楚。
如果 AI 一次给出的代码太长,可以让它拆成模型、仓储、服务、演示入口四个文件分别输出,但要明确约定类名和方法名,避免前后不一致。
三、一段可运行的 Java 示例:内存版任务 CRUD
下面是按上述需求整理后、可直接运行的一段代码。它用内存 Map 代替数据库,只为先把 CRUD 逻辑跑通;确认逻辑无误后,再把仓储层换成数据库实现即可。
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
public class TaskCrudDemo {
enum Status { TODO, DOING, DONE }
static class Task {
private final long id;
private final String title;
private Status status;
private final LocalDateTime createdAt;
Task(long id, String title) {
this.id = id;
this.title = title;
this.status = Status.TODO;
this.createdAt = LocalDateTime.now();
}
public long getId() { return id; }
public String getTitle() { return title; }
public Status getStatus() { return status; }
public void setStatus(Status status) { this.status = status; }
@Override
public String toString() {
return "Task{id=" + id + ", title='" + title + "', status=" + status + ", createdAt=" + createdAt + "}";
}
}
static class TaskService {
private final Map<Long, Task> store = new ConcurrentHashMap<>();
private final AtomicLong idGenerator = new AtomicLong(1);
public Task create(String title) {
if (title == null || title.isBlank()) {
throw new IllegalArgumentException("任务标题不能为空");
}
if (title.length() > 100) {
throw new IllegalArgumentException("任务标题不能超过 100 个字符");
}
long id = idGenerator.getAndIncrement();
Task task = new Task(id, title);
store.put(id, task);
return task;
}
public Task getById(long id) {
Task task = store.get(id);
if (task == null) {
throw new NoSuchElementException("不存在 id 为 " + id + " 的任务");
}
return task;
}
public List<Task> listAll() {
return new ArrayList<>(store.values());
}
public Task updateStatus(long id, Status status) {
Task task = getById(id);
task.setStatus(status);
return task;
}
public void delete(long id) {
if (store.remove(id) == null) {
throw new NoSuchElementException("不存在 id 为 " + id + " 的任务,无法删除");
}
}
}
public static void main(String[] args) {
TaskService service = new TaskService();
Task t1 = service.create("编写接口文档");
Task t2 = service.create("实现任务 CRUD");
System.out.println("全部任务:" + service.listAll());
service.updateStatus(t1.getId(), Status.DOING);
System.out.println("更新后:" + service.getById(t1.getId()));
service.delete(t2.getId());
System.out.println("删除后剩余:" + service.listAll());
try {
service.getById(t2.getId());
} catch (NoSuchElementException e) {
System.out.println("预期异常:" + e.getMessage());
}
}
}
运行 main 方法后,依次输出新增任务、查询全部、更新状态、查询单个、删除后再查询的结果。删除后再次查询会抛出明确的异常信息,而不是返回空值让调用方去猜。
四、逐行核对生成代码:AI 最容易出错的五个地方
AI 生成的代码能跑,不等于没有问题。我核对时会重点看五个地方:一是校验是否真的生效,比如标题为空时是否被拦截;二是异常信息是否明确,是否把“不存在”与“参数错误”混在一起;三是并发安全,内存 Map 在多线程下是否用了线程安全的实现;四是边界条件,比如更新一个不存在的任务、删除两次会发生什么;五是命名与注释是否与实际行为一致,有没有“注释说一套、代码做一套”的情况。
核对的方法也很直接:为每个分支写一条最小的验证用例,跑一遍再提交。这一步不能省,AI 替你写代码,但不能替你对结果负责。
五、把生成代码接进 Spring Boot 与华为云
逻辑跑通后,接进工程的改动其实很小:把内存仓储换成数据库访问,把服务层交给 Spring 管理,再用 Controller 对外暴露接口。调用大模型能力时,建议把模型调用收口成独立的服务,统一管理地址、密钥、超时和重试,业务代码只关心输入和输出。
如果在华为云上做这类实践,可以用 AI DevSpace 的体验版做验证:把生成的代码放进工作区直接运行,边改边验证;需要调用模型能力时,也可以通过 MaaS 以 API 方式接入,不必自己部署模型。先在体验环境把流程跑通,再决定是否落到正式工程里。
六、结语:AI 写代码,人负责让代码可信
AI 辅助生成代码的真正收益,不是少敲几行键盘,而是把“从需求到可运行代码”的反馈周期缩短到几分钟。但前提始终是:需求由人写清楚,代码由人逐行核对,边界由测试覆盖。把这三件事做好,AI 生成的 CRUD 代码才能从“看起来能跑”变成“真的可信”。
- 点赞
- 收藏
- 关注作者
评论(0)