跳到主要内容

创建日期:2026-09-08 | 最近更新:2026-09-08 本篇演示项目 本机实测跑通:JDK 11 + Maven 3.9.16 离线打包并运行,输出见 §4。

Java 复习手册 5:搭一个完整项目(Maven 命令行待办)

前几篇学的是「零件」。这篇把它们组装成第一个能跑的完整项目——一个分层的命令行待办清单:model(数据)→ service(业务)→ Main(入口)。它会把你学过的封装、继承、接口思路落到位,也为将来接 Spring Boot(Java Web 的完整项目形态)打底。

1. 为什么用 Maven,不手敲 javac

javac 适合 1 个文件;项目一多,编译、打包、依赖、测试都要工具管 → 用 Maven(详见本站 Maven 入门)。你只需遵守:

项目根/
├─ pom.xml # 项目声明:坐标、JDK 版本、打包配置
└─ src/main/java/... # 源码目录(按 package 放)

Maven 帮你:编译(compile)→ 测试(test)→ 打 jar(package)。

2. 项目结构:先想清楚「分几层」

一个「能长大」的小项目,至少分三层——这是所有 Java 项目的通用骨架:

放什么对应类
model(领域)数据和自己的基本行为Task
service(业务)怎么管理数据、业务规则TodoService
入口(presentation)跟用户打交道(命令行/HTTP/UI)Main

原则:presentation 不写业务,model 不放逻辑,业务集中在 service。将来把「内存 List」换成数据库,只动 service/数据层,Main 和 Task 不用改。

3. 代码(三段,每段复习一篇)

① Task.java —— 复习「封装 + 构造器 + toString」(篇 2/3)

package com.example.todo;

public class Task {
private final int id; // final:构造后不变
private final String title;
private boolean done;

public Task(int id, String title) {
this.id = id;
this.title = title;
}

public int getId() { return id; }
public String getTitle() { return title; }
public boolean isDone() { return done; }

public void markDone() { this.done = true; }

@Override
public String toString() { // 让打印好看
return (done ? "[x] " : "[ ] ") + id + ". " + title;
}
}

② TodoService.java —— 复习「List/泛型 + 异常 + StringBuilder」(篇 4)

package com.example.todo;

import java.util.ArrayList;
import java.util.List;

public class TodoService {
private final List<Task> tasks = new ArrayList<>(); // 内存当数据库
private int nextId = 1;

public Task add(String title) {
if (title == null || title.trim().isEmpty()) {
throw new IllegalArgumentException("标题不能为空"); // 业务校验 + 异常
}
Task t = new Task(nextId++, title);
tasks.add(t);
return t;
}

public List<Task> all() { return new ArrayList<>(tasks); } // 返回副本

public void complete(int id) {
for (Task t : tasks) {
if (t.getId() == id) { t.markDone(); return; }
}
throw new IllegalArgumentException("找不到 id=" + id + " 的任务");
}

public String render() { // StringBuilder 拼文本
StringBuilder sb = new StringBuilder("待办清单(共 ").append(tasks.size()).append(" 条)\n");
for (Task t : tasks) sb.append(" ").append(t).append('\n');
return sb.toString();
}
}

③ Main.java —— 复习「static main + 输入 + try/catch」(篇 0/4)

package com.example.todo;

import java.util.Scanner;

public class Main {
public static void main(String[] args) {
if (args.length > 0 && "--demo".equals(args[0])) { runDemo(); return; }
interactive();
}

private static void runDemo() {
TodoService svc = new TodoService();
svc.add("复习 Java 语法");
svc.add("搭一个完整项目");
System.out.print(svc.render());
svc.complete(1);
System.out.println("完成 id=1 之后:");
System.out.print(svc.render());
}

private static void interactive() {
TodoService svc = new TodoService();
Scanner in = new Scanner(System.in);
System.out.println("待办清单。命令:add <标题> | done <id> | list | exit");
while (true) {
System.out.print("> ");
String line = in.nextLine();
if (line == null || line.equals("exit")) break;
try {
if (line.startsWith("add ")) svc.add(line.substring(4));
else if (line.startsWith("done ")) svc.complete(Integer.parseInt(line.substring(5).trim()));
else if (line.equals("list")) System.out.print(svc.render());
else System.out.println("看不懂,试试 add xxx / done 1 / list");
} catch (IllegalArgumentException e) {
System.out.println("出错:" + e.getMessage()); // 业务异常 → 友好提示
}
}
}
}

4. 跑起来(本机实测输出)

pom.xml 记得声明主类(maven-jar-plugin<mainClass>),然后:

mvn -o package # 编译 + 打包(-o 离线;首次建议去掉 -o 拉依赖)
java -jar target/todo-cli-1.0.0.jar --demo # 跑内置演示

真实运行输出

待办清单(共 2 条)
[ ] 1. 复习 Java 语法
[ ] 2. 搭一个完整项目
完成 id=1 之后:
待办清单(共 2 条)
[x] 1. 复习 Java 语法
[ ] 2. 搭一个完整项目

交互模式(管道喂命令)真实输出:

> > > > 待办清单(共 2 条)
[x] 1. 复习集合
[ ] 2. 写总结
> bye

看到没:你已经把 0–4 篇所有内容用起来了——package/main、类与封装、List/异常、StringBuilder、遍历。这就是「一个完整项目」的最小闭环。

5. 从 CLI 走向 Web(下一步路线)

命令行待办没有「网页/接口」——那需要把「入口层」从 Main 换成 Web 框架。本站已备好衔接:

  1. 把 Maven 搞熟Maven 入门
  2. Java Web 完整项目Spring & Spring Boot 入门(你会看到一模一样的分层:Controller → Service → …,只是入口变成 HTTP);
  3. 想再补的 Java 知识点:I/O 读文件、多线程、record/switch 新语法、Stream 链式操作——用到再学即可。

收尾:这本手册你「记住」了什么

一句话核心
0.java→javac→.class→java→JVM;public 类名=文件名
18 个基本类型 + String(用 equals)+ 流程控制 + 数组(length 无括号)
2类=图纸、new=实物;封装 private + getter/setter;static 属于类
3单继承 + 接口多实现;抽象类管「是」,接口管「能」;多态看实际类型
4List/Set/Map + 泛型;异常 try/catch/finally;StringBuilder
5model/service/presentation 三层 + Maven 打包 = 完整项目闭环

复习建议:别重读全文,只看每篇的「最容易忘」和「自测」——答得上来就过,答不上来才回去看那一段。重复 2–3 轮,Java 就真的是你的了。

动手

把待办项目改造成:done 能撤销(加个 uncomplete);给 Taskdeadline 字段并按截止时间排序(提示:service 里用 Comparator 或先 List.sort)。改完跑 --demo 看效果。