Hello World:你的第一行 Java 代码
难度:初级 | 预计时间:30 分钟
📖 你的第一行 Java
故事背景
你是一个资深前端,JS/TS 写得飞起。有一天团队需要你写一个定时任务,每天凌晨从 API 拉数据存到数据库。你打开终端,写了个 node script.js,突然想起来——这次的后端服务是 Java 写的。你看着 IDEA 里新建的 HelloWorld.java,心想:不就换个语言吗,能有多难?这第一课,就是你的起点。
💻 代码演示
下面是一个最简 Java 程序的完整生命周期——从源代码到运行:
// HelloWorld.java — 你的第一个 Java 程序
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, Java!");
System.out.println("当前时间: " + java.time.LocalDateTime.now());
}
}运行输出:
Hello, Java!
当前时间: 2026-05-20T21:30:00🎯 三个核心问题
这是什么?
JDK 是 Java Development Kit(开发工具包),包含编译器 javac、运行时、标准库。你写代码用的就是它。
JRE 是 Java Runtime Environment(运行环境),只负责运行,不能编译。
JVM 是 Java Virtual Machine(虚拟机),真正执行字节码的引擎。
为什么需要它?
Java 的口号是 "Write Once, Run Anywhere"(一次编写,到处运行)。编译出的 .class 文件不是机器码,而是 字节码——JVM 把它翻译成不同操作系统能懂的机器指令。你在 Mac 上编译的代码,可以直接放到 Linux 服务器上跑。作为前端,你可以把它类比成:Java 源码 = TypeScript 源码,字节码 = 编译后的 JS,JVM = 浏览器引擎。
如果没有它会怎样?
如果没有 JVM 这层抽象,每种操作系统都要编译一次,C/C++ 就是这么干的——跨平台部署极其痛苦。如果没有编译步骤(像 Python 那样直接解释执行),启动速度和运行效率会大打折扣。Java 选择了中间路线:编译一次,JVM 适配平台差异。
📝 原理讲解
逐行拆解 HelloWorld.java:
public class HelloWorld— 定义一个公开的类。Java 中 一切代码都在类里,没有独立函数。类名必须和文件名完全一致。public static void main(String[] args)— 程序的入口方法。拆开看:public— JVM 需要从外部调用这个方法static— 不需要创建对象就能调用void— main 不返回任何值String[] args— 命令行参数,类似 Node.js 的process.argv
System.out.println()— 标准输出。类比 JS 的console.log()
编译和运行流程:
┌──────────────┐ javac ┌──────────────┐ java ┌──────────────┐
│ HelloWorld │ ──────────────> │ HelloWorld │ ─────────────> │ JVM 执行 │
│ .java │ 编译(一次) │ .class │ 运行(每次) │ 字节码 → 输出 │
│ (源代码) │ │ (字节码) │ │ │
└──────────────┘ └──────────────┘ └──────────────┘🎨 生活类比
类比理解
JDK 是厨房——锅碗瓢盆、食材、食谱一应俱全,你可以做任何菜。 JRE 是微波炉——只负责加热,你不能用它切菜。 JVM 是那个隐形的厨师——同一份食谱(字节码),它能看懂你家煤气灶(Windows)和电磁炉(Mac)各自的说明书,做出一模一样的菜。
用户下载的是微波炉(JRE),你开发用厨房(JDK),而 JVM 是藏在这两者背后的通用引擎。
✏️ 动手练习
练习 1
安装 JDK 17(推荐 brew install openjdk@17),用 java -version 和 javac -version 验证安装。
<details> <summary>💡 查看提示</summary>
Mac: brew install openjdk@17。安装后可能需要设置 JAVA_HOME 环境变量。
</details>
练习 2
新建 HelloWorld.java,写入上面的代码,用 javac HelloWorld.java 编译,再用 java HelloWorld 运行。
<details> <summary>💡 查看提示</summary>
注意:运行时不要加 .class 后缀,直接写类名。
</details>
练习 3
故意制造 3 个编译错误:①删掉一个分号 ②类名和文件名不一致 ③把 String 写成 string。观察报错信息,试着理解它们。
<details> <summary>💡 查看提示</summary>
Java 编译器(javac)的错误信息通常包含行号,格式是 文件名:行号: 错误描述。
</details>
✅ 自检站
<details> <summary><strong>JDK、JRE、JVM 三者的关系是什么?为什么用户只需要 JRE,开发者需要 JDK?</strong></summary>
JDK 包含 JRE + 开发工具(javac 编译器、调试器等)。JRE = JVM + 核心类库。用户只需运行,所以装 JRE 就够了。开发者需要编译、调试,所以用 JDK。类比:你只需要微波炉(JRE)热饭,但做饭的人需要厨房(JDK)。
</details>
<details> <summary><strong>如果 Java 不编译成字节码,而是像 Python 直接解释执行,会有什么不同?</strong></summary>
启动会更快(省去编译步骤),但运行会慢很多——解释器需要逐行分析源码。编译成字节码后,JVM 可以在运行时对热点代码做 JIT(即时编译)优化,性能接近原生代码。Java 的设计在开发效率和执行效率之间取了一个平衡点。
</details>
<details> <summary><strong>public static void main(String[] args) 中每个关键字各有什么用?</strong></summary>
public = 外部可访问(JVM 需要调用);static = 无需实例化即可调用;void = 无返回值;main = 约定入口方法名;String[] args = 命令行参数数组。
</details>