这篇教程不从 Hello World 停下,而是建立一个可以持续修改的 Java 21 小项目。完成后,你能解释源码放在哪里、
依赖从哪里来,以及为什么本机运行成功不等于项目可交付。
Table of contents
先运行起来
建立以下结构。你也可以下载示例的 pom.xml下载、 生产代码下载和 测试代码下载。 约定优于配置是指工具通过固定目录识别文件用途,从而减少重复配置。
问候服务/
├── pom.xml
└── src/
├── main/java/dev/elaine/basics/GreetingService.java
└── test/java/dev/elaine/basics/GreetingServiceTest.java
GreetingService.java:
package dev.elaine.basics;
public final class GreetingService {
public String greet(String name) {
if (name == null || name.isBlank()) {
throw new IllegalArgumentException("姓名不能为空");
}
return "你好," + name + "!";
}
public static void main(String[] args) {
System.out.println(new GreetingService().greet("Java 学习者"));
}
}
测试描述预期行为,而不是重复实现:
package dev.elaine.basics;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class GreetingServiceTest {
@Test void 返回带姓名的问候语() {
assertEquals("你好,Elaine!", new GreetingService().greet("Elaine"));
}
@Test void 拒绝空姓名() {
assertThrows(IllegalArgumentException.class,
() -> new GreetingService().greet(" "));
}
}
在项目根目录生成 Wrapper,再运行测试和程序:
mvn wrapper:wrapper -Dmaven=3.9.14
mvn test
mvn exec:java -Dexec.mainClass=dev.elaine.basics.GreetingService
看懂构建生命周期
**生命周期(Lifecycle)**是 Maven 规定的一组有顺序的构建阶段。执行后面的阶段,会先执行前面的阶段。
| 命令 | 发生什么 | 什么时候用 |
|---|---|---|
mvn compile | 编译生产源码 | 快速检查语法 |
mvn test | 编译并运行单元测试 | 日常开发 |
mvn package | 测试后生成 JAR | 准备交付 |
mvn verify | 执行额外质量检查 | CI 合并门禁 |
**依赖(Dependency)**是项目编译或运行所需的外部库。JUnit 应使用 test Scope,表示它只进入测试类路径,
不会混入生产包。依赖版本和构建插件都应写入 pom.xml,Maven Wrapper 也应提交到 Git。
用失败验证测试有效
先把预期字符串改成错误值,再运行 mvn test。测试必须失败,并显示“期望值”和“实际值”。然后还原代码,
确认测试重新通过。这个步骤叫负向验证:故意制造错误,证明报警器真的接通了。
常见失败定位顺序:先读第一个 Caused by,再看自己代码的第一行堆栈,最后才搜索完整错误信息。不要一看到红色输出
就删除测试或跳过测试。
完成标准
- 新机器安装 JDK 和 Maven 后,用
mvn test就能验证项目。 target/没有提交到 Git,Wrapper 和pom.xml已提交。- 正常输入、边界输入和错误输入至少各有一个测试。
下一步
阅读类型系统、值传递与对象引用,理解方法参数传递 的究竟是值还是对象。