在编程学习中,有一个延续了半个多世纪的传统——用"Hello World"作为你的第一个程序。本文将带领你从零开始,一行一行地编写、编译并运行你的第一个Java程序。不需要任何编程基础,只需要一台电脑和一颗愿意学习的心。
一、"Hello World"的传统与意义
1.1 起源
"Hello World"的历史可以追溯到1972年。当时,贝尔实验室的Brian Kernighan在撰写《A Tutorial Introduction to the Language B》时,首次使用了一个输出"hello, world"的示例程序。1978年,Brian Kernighan与Dennis Ritchie合著的《The C Programming Language》一书中,正式将"hello, world"这个示例程序推向了全世界。
// 1978年 K&R C语言教材中的原始示例
#include <stdio.h>
main()
{
printf("hello, world\\n");
}
从那时起,几乎每一门编程语言的初学者教程,都会以"Hello World"作为第一个程序示例。"Hello World"已经成为编程文化中不可磨灭的符号。
1.2 为什么从"Hello World"开始
选择"Hello World"作为第一个程序,背后蕴含着深刻的教学智慧。下表总结了它的核心意义:
| 最小化认知负担 | 程序仅实现最简单的输出功能,让初学者专注于理解编程环境的搭建和基本流程 |
| 验证环境正确性 | 成功运行"Hello World"意味着JDK安装正确、环境变量配置无误、编译和运行流程通畅 |
| 建立正向反馈 | 看到屏幕上输出自己亲手编写的文字,给人以强烈的成就感和继续学习的动力 |
| 理解程序生命周期 | 经历"编写源码-编译-运行-输出结果"的完整流程,建立对程序执行全过程的概念 |
| 跨语言对比基准 | 用同一功能对比不同语言的语法差异,是理解语言特性的绝佳切入点 |
编者按: 程序员圈子里流传着一个有趣的说法——如果你不能用一门新语言写出"Hello World",那么你还没准备好学习它。这句话虽然夸张,但却道出了一个事实:能够运行"Hello World"意味着你已经克服了学习一门语言的第一道门槛——环境搭建与基本编译执行流程。
1.3 一个仪式感的开始
对于许多程序员来说,用一门新语言写出"Hello World",就像一种仪式。它标志着一段新的学习旅程的开始。当你在屏幕上看到"Hello World"的那一刻,你已经正式踏入了Java编程的世界。
二、准备工作:确保环境就绪
在开始编写代码之前,需要确保你的电脑上已经安装了JDK并正确配置了环境变量。如果你还没有完成这一步,请参考本系列第2篇文章。
2.1 验证JDK安装
打开命令提示符(Windows按Win + R,输入cmd回车)或终端(macOS/Linux),执行以下命令:
java -version
如果看到类似以下输出,说明JDK安装成功:
java version "21.0.1" 2023-10-17 LTS
Java(TM) SE Runtime Environment (build 21.0.1+12-LTS-29)
Java HotSpot(TM) 64-Bit Server VM (build 21.0.1+12-LTS-29, mixed mode, sharing)
再验证编译器是否可用:
javac -version
预期输出:
javac 21.0.1
两条命令都能正常输出版本号,说明你的Java环境已经准备就绪。下面我们正式开始编写代码。
三、创建第一个Java源文件
3.1 选择工作目录
首先,在电脑上创建一个专门存放Java代码的文件夹。建议在D盘(或你常用的盘符)根目录下创建:
# Windows
mkdir D:\\JavaProjects
cd D:\\JavaProjects
# macOS / Linux
mkdir ~/JavaProjects
cd ~/JavaProjects
3.2 创建HelloWorld.java文件
在你选择的工作目录下,创建一个名为HelloWorld.java的文件。你可以用任何文本编辑器(记事本、VS Code、Sublime Text、Notepad++等)来创建。
重要提示:
- 文件名必须为HelloWorld.java,大小写完全一致
- 如果你使用Windows记事本,保存时注意"保存类型"选择"所有文件",编码选择"UTF-8",否则文件可能会被自动加上.txt后缀变成HelloWorld.java.txt
- 确保文件扩展名是.java而不是.txt或其他
3.3 显示文件扩展名(Windows用户必看)
Windows系统默认隐藏已知文件类型的扩展名,这常常导致初学者创建出HelloWorld.java.txt这样的文件。建议按以下步骤显示文件扩展名:
这样你就能清楚地看到文件的实际扩展名了。
四、编写Java代码
4.1 完整代码
打开HelloWorld.java文件,输入以下代码:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
这就是一个完整的、可以运行的最简Java程序。代码虽然只有5行,但每一部分都承载着重要的语法含义。下面我们将对它进行逐行、逐词的深度解析。
4.2 第一行:public class HelloWorld {
这是Java程序的"大门",我们来拆解每一个部分。
4.2.1 public —— 访问修饰符
public是一个访问修饰符(Access Modifier),它表示这个类对所有其他类都是可见和可访问的。Java中有四种访问级别:
| private | 可访问 | 不可访问 | 不可访问 | 不可访问 |
| default(不写) | 可访问 | 可访问 | 不可访问 | 不可访问 |
| protected | 可访问 | 可访问 | 可访问 | 不可访问 |
| public | 可访问 | 可访问 | 可访问 | 可访问 |
对于主类(包含main方法的类),我们通常使用public修饰,以便JVM能够找到并加载它。
4.2.2 class —— 定义类的关键字
class是Java中定义类的关键字。Java是一种纯面向对象的编程语言,一切代码都必须写在类中。每个.java源文件中可以定义多个类,但只能有一个public类。
理解"类"的概念: 可以把类理解为一个"蓝图"或"模板"。就像建筑图纸描述了一栋房子的结构一样,类描述了对象的属性和行为。对于HelloWorld这个简单的程序来说,我们可以把这个类理解为一个"程序容器"——它是装载我们程序逻辑的外壳。
4.2.3 HelloWorld —— 类名
HelloWorld是这个类的名称。类名必须遵循以下规则:
| 使用PascalCase(大驼峰命名法) | 每个单词首字母大写 | HelloWorld, StudentManager | helloworld, hello_world |
| 由字母、数字、下划线、美元符号组成 | 不能包含空格和特殊字符 | MyClass1, Test_02 | My Class, Test-01 |
| 不能以数字开头 | 首字符必须为字母或下划线 | Class1 | 1Class |
| 不能使用Java关键字 | 不能用class、int等保留字 | MyClass | class |
| 与文件名一致(public类) | public类的类名必须与.java文件名完全相同 | 文件名HelloWorld.java | 文件名hello.java |
4.2.4 { —— 类体的开始
左花括号{标志着类定义体的开始。与之对应,文件最后一行有一个右花括号}标志着类体的结束。花括号之间的所有代码都属于这个类。
4.3 第二行:public static void main(String[] args) {
这是整个程序的"入口",是Java程序中最重要的一行代码。让我们逐词分析。
#mermaid-svg-dOTcseX1tAza33TC{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-dOTcseX1tAza33TC .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-dOTcseX1tAza33TC .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-dOTcseX1tAza33TC .error-icon{fill:#552222;}#mermaid-svg-dOTcseX1tAza33TC .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-dOTcseX1tAza33TC .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-dOTcseX1tAza33TC .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-dOTcseX1tAza33TC .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-dOTcseX1tAza33TC .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-dOTcseX1tAza33TC .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-dOTcseX1tAza33TC .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-dOTcseX1tAza33TC .marker{fill:#333333;stroke:#333333;}#mermaid-svg-dOTcseX1tAza33TC .marker.cross{stroke:#333333;}#mermaid-svg-dOTcseX1tAza33TC svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-dOTcseX1tAza33TC p{margin:0;}#mermaid-svg-dOTcseX1tAza33TC .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-dOTcseX1tAza33TC .cluster-label text{fill:#333;}#mermaid-svg-dOTcseX1tAza33TC .cluster-label span{color:#333;}#mermaid-svg-dOTcseX1tAza33TC .cluster-label span p{background-color:transparent;}#mermaid-svg-dOTcseX1tAza33TC .label text,#mermaid-svg-dOTcseX1tAza33TC span{fill:#333;color:#333;}#mermaid-svg-dOTcseX1tAza33TC .node rect,#mermaid-svg-dOTcseX1tAza33TC .node circle,#mermaid-svg-dOTcseX1tAza33TC .node ellipse,#mermaid-svg-dOTcseX1tAza33TC .node polygon,#mermaid-svg-dOTcseX1tAza33TC .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-dOTcseX1tAza33TC .rough-node .label text,#mermaid-svg-dOTcseX1tAza33TC .node .label text,#mermaid-svg-dOTcseX1tAza33TC .image-shape .label,#mermaid-svg-dOTcseX1tAza33TC .icon-shape .label{text-anchor:middle;}#mermaid-svg-dOTcseX1tAza33TC .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-dOTcseX1tAza33TC .rough-node .label,#mermaid-svg-dOTcseX1tAza33TC .node .label,#mermaid-svg-dOTcseX1tAza33TC .image-shape .label,#mermaid-svg-dOTcseX1tAza33TC .icon-shape .label{text-align:center;}#mermaid-svg-dOTcseX1tAza33TC .node.clickable{cursor:pointer;}#mermaid-svg-dOTcseX1tAza33TC .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-dOTcseX1tAza33TC .arrowheadPath{fill:#333333;}#mermaid-svg-dOTcseX1tAza33TC .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-dOTcseX1tAza33TC .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-dOTcseX1tAza33TC .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dOTcseX1tAza33TC .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-dOTcseX1tAza33TC .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dOTcseX1tAza33TC .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-dOTcseX1tAza33TC .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-dOTcseX1tAza33TC .cluster text{fill:#333;}#mermaid-svg-dOTcseX1tAza33TC .cluster span{color:#333;}#mermaid-svg-dOTcseX1tAza33TC div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-dOTcseX1tAza33TC .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-dOTcseX1tAza33TC rect.text{fill:none;stroke-width:0;}#mermaid-svg-dOTcseX1tAza33TC .icon-shape,#mermaid-svg-dOTcseX1tAza33TC .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-dOTcseX1tAza33TC .icon-shape p,#mermaid-svg-dOTcseX1tAza33TC .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-dOTcseX1tAza33TC .icon-shape .label rect,#mermaid-svg-dOTcseX1tAza33TC .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-dOTcseX1tAza33TC .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-dOTcseX1tAza33TC .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-dOTcseX1tAza33TC :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
main方法签名
访问修饰符
静态修饰符
返回类型
方法名
参数列表
public
整个签名
static
void
main
(String[] args)
4.3.1 public —— 访问修饰符
与类的public含义相同。main方法必须声明为public,因为JVM需要从类的外部调用这个方法。如果main方法不是public,JVM将无法访问它,程序运行时会报错。
4.3.2 static —— 静态修饰符
static表示这是一个静态方法,它属于类本身,而不是类的某个实例。这是至关重要的设计——JVM在启动时还没有创建任何对象,它只能调用属于类本身的静态方法。没有static修饰,JVM就无法在不创建对象的情况下调用main方法。
理解static的一个比喻:
类的静态成员 → 像是公共图书馆的书,任何人都可以直接去借阅
类的实例成员 → 像是私人家中的书,必须先认识这个人(创建对象)才能借阅
4.3.3 void —— 返回类型
void表示这个方法不返回任何值。main方法执行完毕后,程序就结束了,不需要向JVM返回任何结果。如果一个方法需要返回一个整数,就会用int代替void;如果需要返回字符串,就会用String代替void。
4.3.4 main —— 方法名
main是Java程序的入口方法名称,这是一个约定——JVM在启动时会自动寻找名为main的方法来执行。方法名必须完全拼写为main,不能写成Main、MAIN或main1,因为Java是严格区分大小写的。
为什么必须是"main"? 这是Java语言规范(JLS)的硬性规定。JVM在加载主类后,会通过反射机制查找签名恰好为public static void main(String[])的方法。方法名不匹配将导致JVM报错:找不到main方法。
4.3.5 (String[] args) —— 参数列表
这是main方法的参数列表,它接收一个String类型的数组。拆解如下:
- String:Java中的字符串类型,用于存储文本数据
- []:表示这是一个数组(Array),可以容纳多个同类型的元素
- args:参数名称,可以自定义(如arguments、params),但Java社区约定俗成使用args
这个参数的作用是接收命令行参数。当你在命令行中这样运行程序:
java HelloWorld 张三 李四 王五
那么args数组的内容就是:
args[0] = "张三"
args[1] = "李四"
args[2] = "王五"
关于String数组的声明,Java支持两种等价的写法:
// 写法一:传统C/C++风格(推荐使用)
public static void main(String[] args)
// 写法二:Java独有风格(语法上等价)
public static void main(String args[])
两者在编译后没有任何区别。Java社区更推荐第一种写法,因为它更清晰地体现了String[]是一个整体类型。
4.3.6 { —— 方法体的开始
与类体的花括号类似,这标志着main方法体的开始。方法体中的代码就是程序实际要执行的指令。
4.4 第三行:System.out.println("Hello World");
这是整个程序唯一的功能代码——在控制台输出一行文本。它由三个部分通过点号.连接而成。
4.4.1 System —— 系统类
System是java.lang包中的一个类,它提供了许多与系统相关的实用工具。java.lang包是Java语言的核心包,会被自动导入,所以不需要写import java.lang.System;。
System类提供了以下常用功能:
| 标准输出流 | System.out | 向控制台输出信息 |
| 标准输入流 | System.in | 从键盘读取输入 |
| 标准错误流 | System.err | 输出错误信息(通常也显示在控制台) |
| 获取系统属性 | System.getProperty(…) | 获取操作系统名称、Java版本等信息 |
| 获取当前时间 | System.currentTimeMillis() | 获取当前时间的毫秒值 |
| 退出程序 | System.exit(0) | 终止JVM运行 |
| 数组复制 | System.arraycopy(…) | 高效复制数组元素 |
4.4.2 out —— 标准输出流对象
out是System类中的一个静态字段(static field),类型为PrintStream(打印流)。因为它是静态的,所以我们可以通过System.out直接访问它,而不需要先创建System对象。
out代表标准输出流(Standard Output Stream),默认连接到控制台(显示器)。当你向out写入内容时,这些内容就会显示在命令行窗口中。
4.4.3 println(…) —— 打印并换行的方法
println是PrintStream类提供的实例方法,用于输出文本并自动在末尾添加换行符。名称是"print line"的缩写。
// println:输出后换行
System.out.println("第一行");
System.out.println("第二行");
// 输出:
// 第一行
// 第二行
// print:输出后不换行
System.out.print("Hello ");
System.out.print("World");
// 输出:
// Hello World
println方法有多个重载版本,可以接受不同类型的参数:
System.out.println("字符串"); // 输出字符串
System.out.println(100); // 输出整数:100
System.out.println(3.14); // 输出浮点数:3.14
System.out.println(true); // 输出布尔值:true
System.out.println('A'); // 输出字符:A
System.out.println(); // 只输出一个空行
4.4.4 "Hello World" —— 字符串字面量
用双引号包裹的文本就是字符串字面量(String Literal)。Java中字符串必须使用双引号,单引号用于单个字符:
"Hello World" // 字符串,正确 ✓
"你好世界" // 中文字符串,也可以 ✓
'H' // 单个字符,正确 ✓
'Hello World' // 错误!不能用单引号包裹多个字符 ✗
4.4.5 ; —— 语句结束符
分号;标志着一条Java语句的结束。在Java中,几乎每一条执行指令都必须以分号结尾。这与Python等语言不同——Python用换行来分隔语句,而Java用分号。
遗漏分号是初学者最容易犯的错误之一:
// 错误:缺少分号
System.out.println("Hello World") // 编译错误!
// 正确
System.out.println("Hello World"); // 正确 ✓
五、编译:将源代码转化为字节码
5.1 什么是编译
编译(Compile)是将人类可读的源代码(Source Code)转化为计算机可执行的机器码或中间码的过程。Java的编译过程有其独特之处——它并不直接将源代码编译为特定操作系统的机器码,而是编译为一种中间格式:字节码(Bytecode)。
#mermaid-svg-b2DyHVRvvgAKRc9n{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-b2DyHVRvvgAKRc9n .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-b2DyHVRvvgAKRc9n .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-b2DyHVRvvgAKRc9n .error-icon{fill:#552222;}#mermaid-svg-b2DyHVRvvgAKRc9n .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-b2DyHVRvvgAKRc9n .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-b2DyHVRvvgAKRc9n .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-b2DyHVRvvgAKRc9n .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-b2DyHVRvvgAKRc9n .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-b2DyHVRvvgAKRc9n .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-b2DyHVRvvgAKRc9n .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-b2DyHVRvvgAKRc9n .marker{fill:#333333;stroke:#333333;}#mermaid-svg-b2DyHVRvvgAKRc9n .marker.cross{stroke:#333333;}#mermaid-svg-b2DyHVRvvgAKRc9n svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-b2DyHVRvvgAKRc9n p{margin:0;}#mermaid-svg-b2DyHVRvvgAKRc9n .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-b2DyHVRvvgAKRc9n .cluster-label text{fill:#333;}#mermaid-svg-b2DyHVRvvgAKRc9n .cluster-label span{color:#333;}#mermaid-svg-b2DyHVRvvgAKRc9n .cluster-label span p{background-color:transparent;}#mermaid-svg-b2DyHVRvvgAKRc9n .label text,#mermaid-svg-b2DyHVRvvgAKRc9n span{fill:#333;color:#333;}#mermaid-svg-b2DyHVRvvgAKRc9n .node rect,#mermaid-svg-b2DyHVRvvgAKRc9n .node circle,#mermaid-svg-b2DyHVRvvgAKRc9n .node ellipse,#mermaid-svg-b2DyHVRvvgAKRc9n .node polygon,#mermaid-svg-b2DyHVRvvgAKRc9n .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-b2DyHVRvvgAKRc9n .rough-node .label text,#mermaid-svg-b2DyHVRvvgAKRc9n .node .label text,#mermaid-svg-b2DyHVRvvgAKRc9n .image-shape .label,#mermaid-svg-b2DyHVRvvgAKRc9n .icon-shape .label{text-anchor:middle;}#mermaid-svg-b2DyHVRvvgAKRc9n .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-b2DyHVRvvgAKRc9n .rough-node .label,#mermaid-svg-b2DyHVRvvgAKRc9n .node .label,#mermaid-svg-b2DyHVRvvgAKRc9n .image-shape .label,#mermaid-svg-b2DyHVRvvgAKRc9n .icon-shape .label{text-align:center;}#mermaid-svg-b2DyHVRvvgAKRc9n .node.clickable{cursor:pointer;}#mermaid-svg-b2DyHVRvvgAKRc9n .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-b2DyHVRvvgAKRc9n .arrowheadPath{fill:#333333;}#mermaid-svg-b2DyHVRvvgAKRc9n .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-b2DyHVRvvgAKRc9n .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-b2DyHVRvvgAKRc9n .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-b2DyHVRvvgAKRc9n .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-b2DyHVRvvgAKRc9n .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-b2DyHVRvvgAKRc9n .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-b2DyHVRvvgAKRc9n .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-b2DyHVRvvgAKRc9n .cluster text{fill:#333;}#mermaid-svg-b2DyHVRvvgAKRc9n .cluster span{color:#333;}#mermaid-svg-b2DyHVRvvgAKRc9n div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-b2DyHVRvvgAKRc9n .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-b2DyHVRvvgAKRc9n rect.text{fill:none;stroke-width:0;}#mermaid-svg-b2DyHVRvvgAKRc9n .icon-shape,#mermaid-svg-b2DyHVRvvgAKRc9n .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-b2DyHVRvvgAKRc9n .icon-shape p,#mermaid-svg-b2DyHVRvvgAKRc9n .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-b2DyHVRvvgAKRc9n .icon-shape .label rect,#mermaid-svg-b2DyHVRvvgAKRc9n .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-b2DyHVRvvgAKRc9n .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-b2DyHVRvvgAKRc9n .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-b2DyHVRvvgAKRc9n :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
javac 编译
JVM 解释/编译执行
HelloWorld.java(源代码文件)
HelloWorld.class(字节码文件)
操作系统(Windows/Linux/macOS)
这种设计实现了 “一次编写,到处运行” (Write Once, Run Anywhere, WORA):
#mermaid-svg-DGQYpmVby4st6bpw{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-DGQYpmVby4st6bpw .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-DGQYpmVby4st6bpw .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-DGQYpmVby4st6bpw .error-icon{fill:#552222;}#mermaid-svg-DGQYpmVby4st6bpw .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-DGQYpmVby4st6bpw .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-DGQYpmVby4st6bpw .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-DGQYpmVby4st6bpw .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-DGQYpmVby4st6bpw .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-DGQYpmVby4st6bpw .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-DGQYpmVby4st6bpw .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-DGQYpmVby4st6bpw .marker{fill:#333333;stroke:#333333;}#mermaid-svg-DGQYpmVby4st6bpw .marker.cross{stroke:#333333;}#mermaid-svg-DGQYpmVby4st6bpw svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-DGQYpmVby4st6bpw p{margin:0;}#mermaid-svg-DGQYpmVby4st6bpw .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-DGQYpmVby4st6bpw .cluster-label text{fill:#333;}#mermaid-svg-DGQYpmVby4st6bpw .cluster-label span{color:#333;}#mermaid-svg-DGQYpmVby4st6bpw .cluster-label span p{background-color:transparent;}#mermaid-svg-DGQYpmVby4st6bpw .label text,#mermaid-svg-DGQYpmVby4st6bpw span{fill:#333;color:#333;}#mermaid-svg-DGQYpmVby4st6bpw .node rect,#mermaid-svg-DGQYpmVby4st6bpw .node circle,#mermaid-svg-DGQYpmVby4st6bpw .node ellipse,#mermaid-svg-DGQYpmVby4st6bpw .node polygon,#mermaid-svg-DGQYpmVby4st6bpw .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-DGQYpmVby4st6bpw .rough-node .label text,#mermaid-svg-DGQYpmVby4st6bpw .node .label text,#mermaid-svg-DGQYpmVby4st6bpw .image-shape .label,#mermaid-svg-DGQYpmVby4st6bpw .icon-shape .label{text-anchor:middle;}#mermaid-svg-DGQYpmVby4st6bpw .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-DGQYpmVby4st6bpw .rough-node .label,#mermaid-svg-DGQYpmVby4st6bpw .node .label,#mermaid-svg-DGQYpmVby4st6bpw .image-shape .label,#mermaid-svg-DGQYpmVby4st6bpw .icon-shape .label{text-align:center;}#mermaid-svg-DGQYpmVby4st6bpw .node.clickable{cursor:pointer;}#mermaid-svg-DGQYpmVby4st6bpw .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-DGQYpmVby4st6bpw .arrowheadPath{fill:#333333;}#mermaid-svg-DGQYpmVby4st6bpw .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-DGQYpmVby4st6bpw .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-DGQYpmVby4st6bpw .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DGQYpmVby4st6bpw .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-DGQYpmVby4st6bpw .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DGQYpmVby4st6bpw .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-DGQYpmVby4st6bpw .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-DGQYpmVby4st6bpw .cluster text{fill:#333;}#mermaid-svg-DGQYpmVby4st6bpw .cluster span{color:#333;}#mermaid-svg-DGQYpmVby4st6bpw div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-DGQYpmVby4st6bpw .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-DGQYpmVby4st6bpw rect.text{fill:none;stroke-width:0;}#mermaid-svg-DGQYpmVby4st6bpw .icon-shape,#mermaid-svg-DGQYpmVby4st6bpw .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DGQYpmVby4st6bpw .icon-shape p,#mermaid-svg-DGQYpmVby4st6bpw .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-DGQYpmVby4st6bpw .icon-shape .label rect,#mermaid-svg-DGQYpmVby4st6bpw .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DGQYpmVby4st6bpw .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-DGQYpmVby4st6bpw .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-DGQYpmVby4st6bpw :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
javac
Windows JVM
Linux JVM
macOS JVM
HelloWorld.java
HelloWorld.class(字节码)
Windows
Linux
macOS
5.2 执行编译命令
打开命令行,切换到HelloWorld.java所在的目录,执行编译命令:
javac HelloWorld.java
注意:
- 命令是javac(java compiler),不是java
- 文件名必须包含.java扩展名
- 文件名大小写必须与实际文件完全一致
- 如果路径中包含空格,需要用双引号包裹整个路径
编译成功的标志是:没有任何输出信息。在命令行世界中,没有消息就是好消息。编译成功后,你会在同一目录下发现一个新文件:HelloWorld.class。
# 查看编译结果
dir HelloWorld.* # Windows
ls -l HelloWorld.* # macOS/Linux
预期看到两个文件:
HelloWorld.java (源代码文件)
HelloWorld.class (字节码文件)
5.3 编译过程中发生了什么
#mermaid-svg-GqOiK8XW5LRKC7fb{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-GqOiK8XW5LRKC7fb .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-GqOiK8XW5LRKC7fb .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-GqOiK8XW5LRKC7fb .error-icon{fill:#552222;}#mermaid-svg-GqOiK8XW5LRKC7fb .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-GqOiK8XW5LRKC7fb .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-GqOiK8XW5LRKC7fb .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-GqOiK8XW5LRKC7fb .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-GqOiK8XW5LRKC7fb .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-GqOiK8XW5LRKC7fb .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-GqOiK8XW5LRKC7fb .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-GqOiK8XW5LRKC7fb .marker{fill:#333333;stroke:#333333;}#mermaid-svg-GqOiK8XW5LRKC7fb .marker.cross{stroke:#333333;}#mermaid-svg-GqOiK8XW5LRKC7fb svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-GqOiK8XW5LRKC7fb p{margin:0;}#mermaid-svg-GqOiK8XW5LRKC7fb .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-GqOiK8XW5LRKC7fb .cluster-label text{fill:#333;}#mermaid-svg-GqOiK8XW5LRKC7fb .cluster-label span{color:#333;}#mermaid-svg-GqOiK8XW5LRKC7fb .cluster-label span p{background-color:transparent;}#mermaid-svg-GqOiK8XW5LRKC7fb .label text,#mermaid-svg-GqOiK8XW5LRKC7fb span{fill:#333;color:#333;}#mermaid-svg-GqOiK8XW5LRKC7fb .node rect,#mermaid-svg-GqOiK8XW5LRKC7fb .node circle,#mermaid-svg-GqOiK8XW5LRKC7fb .node ellipse,#mermaid-svg-GqOiK8XW5LRKC7fb .node polygon,#mermaid-svg-GqOiK8XW5LRKC7fb .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-GqOiK8XW5LRKC7fb .rough-node .label text,#mermaid-svg-GqOiK8XW5LRKC7fb .node .label text,#mermaid-svg-GqOiK8XW5LRKC7fb .image-shape .label,#mermaid-svg-GqOiK8XW5LRKC7fb .icon-shape .label{text-anchor:middle;}#mermaid-svg-GqOiK8XW5LRKC7fb .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-GqOiK8XW5LRKC7fb .rough-node .label,#mermaid-svg-GqOiK8XW5LRKC7fb .node .label,#mermaid-svg-GqOiK8XW5LRKC7fb .image-shape .label,#mermaid-svg-GqOiK8XW5LRKC7fb .icon-shape .label{text-align:center;}#mermaid-svg-GqOiK8XW5LRKC7fb .node.clickable{cursor:pointer;}#mermaid-svg-GqOiK8XW5LRKC7fb .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-GqOiK8XW5LRKC7fb .arrowheadPath{fill:#333333;}#mermaid-svg-GqOiK8XW5LRKC7fb .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-GqOiK8XW5LRKC7fb .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-GqOiK8XW5LRKC7fb .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GqOiK8XW5LRKC7fb .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-GqOiK8XW5LRKC7fb .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GqOiK8XW5LRKC7fb .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-GqOiK8XW5LRKC7fb .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-GqOiK8XW5LRKC7fb .cluster text{fill:#333;}#mermaid-svg-GqOiK8XW5LRKC7fb .cluster span{color:#333;}#mermaid-svg-GqOiK8XW5LRKC7fb div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-GqOiK8XW5LRKC7fb .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-GqOiK8XW5LRKC7fb rect.text{fill:none;stroke-width:0;}#mermaid-svg-GqOiK8XW5LRKC7fb .icon-shape,#mermaid-svg-GqOiK8XW5LRKC7fb .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GqOiK8XW5LRKC7fb .icon-shape p,#mermaid-svg-GqOiK8XW5LRKC7fb .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-GqOiK8XW5LRKC7fb .icon-shape .label rect,#mermaid-svg-GqOiK8XW5LRKC7fb .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GqOiK8XW5LRKC7fb .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-GqOiK8XW5LRKC7fb .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-GqOiK8XW5LRKC7fb :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
词法分析
语法分析
语义分析
生成字节码
输出.class文件
将源代码分解为token序列识别关键字、标识符、运算符等
根据语法规则构建抽象语法树AST
检查类型匹配、变量声明等语义正确性
将AST转换为平台无关的JVM字节码指令
| 词法分析 | 将源代码字符流分解为有意义的token(词法单元) | 非法字符、未闭合的字符串等 |
| 语法分析 | 根据Java语法规则,将token序列组织为抽象语法树(AST) | 缺少分号、括号不匹配等语法错误 |
| 语义分析 | 检查语义正确性:类型是否匹配、变量是否已声明等 | 类型不匹配、找不到符号等 |
| 字节码生成 | 将AST转换为.class文件中的JVM指令 | 通常在此阶段前所有错误已被发现 |
| 代码优化 | javac会进行一些基本优化(常量折叠、死代码消除) | — |
5.4 一窥字节码
对于好奇心强的读者,你可以使用javap命令来反编译字节码文件,查看JVM实际执行的指令:
javap -c HelloWorld
输出类似:
Compiled from "HelloWorld.java"
public class HelloWorld {
public HelloWorld();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #13 // String Hello World
5: invokevirtual #19 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
}
你会发现编译器自动生成了一个HelloWorld()构造方法(即使我们没有写),而main方法中的那条System.out.println被翻译成了三条JVM指令。这些细节让你看到Java编译的底层运作方式。
六、运行:让程序在JVM上执行
6.1 执行运行命令
编译成功后,使用java命令来运行程序:
java HelloWorld
关键注意事项:
- 命令是java,不是javac
- 不要加.class扩展名——JVM会自动查找HelloWorld.class
- 类名大小写必须与编译时完全一致
- 当前目录必须在HelloWorld.class所在目录,或者该目录已在classpath中
预期输出:
Hello World
6.2 JVM如何加载并执行程序
执行引擎
方法区/堆
类加载器
Java虚拟机
命令行
用户
执行引擎
方法区/堆
类加载器
Java虚拟机
命令行
用户
#mermaid-svg-TfVPVJ3DH08dVSRL{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-TfVPVJ3DH08dVSRL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-TfVPVJ3DH08dVSRL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-TfVPVJ3DH08dVSRL .error-icon{fill:#552222;}#mermaid-svg-TfVPVJ3DH08dVSRL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-TfVPVJ3DH08dVSRL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-TfVPVJ3DH08dVSRL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-TfVPVJ3DH08dVSRL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-TfVPVJ3DH08dVSRL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-TfVPVJ3DH08dVSRL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-TfVPVJ3DH08dVSRL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-TfVPVJ3DH08dVSRL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-TfVPVJ3DH08dVSRL .marker.cross{stroke:#333333;}#mermaid-svg-TfVPVJ3DH08dVSRL svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-TfVPVJ3DH08dVSRL p{margin:0;}#mermaid-svg-TfVPVJ3DH08dVSRL .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-TfVPVJ3DH08dVSRL text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-TfVPVJ3DH08dVSRL .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-TfVPVJ3DH08dVSRL .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-TfVPVJ3DH08dVSRL .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-TfVPVJ3DH08dVSRL .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-TfVPVJ3DH08dVSRL #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-TfVPVJ3DH08dVSRL .sequenceNumber{fill:white;}#mermaid-svg-TfVPVJ3DH08dVSRL #sequencenumber{fill:#333;}#mermaid-svg-TfVPVJ3DH08dVSRL #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-TfVPVJ3DH08dVSRL .messageText{fill:#333;stroke:none;}#mermaid-svg-TfVPVJ3DH08dVSRL .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-TfVPVJ3DH08dVSRL .labelText,#mermaid-svg-TfVPVJ3DH08dVSRL .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-TfVPVJ3DH08dVSRL .loopText,#mermaid-svg-TfVPVJ3DH08dVSRL .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-TfVPVJ3DH08dVSRL .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-TfVPVJ3DH08dVSRL .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-TfVPVJ3DH08dVSRL .noteText,#mermaid-svg-TfVPVJ3DH08dVSRL .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-TfVPVJ3DH08dVSRL .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-TfVPVJ3DH08dVSRL .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-TfVPVJ3DH08dVSRL .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-TfVPVJ3DH08dVSRL .actorPopupMenu{position:absolute;}#mermaid-svg-TfVPVJ3DH08dVSRL .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-TfVPVJ3DH08dVSRL .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-TfVPVJ3DH08dVSRL .actor-man circle,#mermaid-svg-TfVPVJ3DH08dVSRL line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-TfVPVJ3DH08dVSRL :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
1. 检查是否已加载
2. 委托父类加载器
3. 自身加载class文件
字节码验证
1. 文件格式验证
2. 元数据验证
3. 字节码验证
4. 符号引用验证
java HelloWorld
启动JVM进程
查找并加载 HelloWorld.class
双亲委派模型加载
将类元数据存入方法区
验证字节码格式
查找 main(String[]) 方法
在栈中创建main方法栈帧
逐条执行字节码指令
System.out.println("Hello World")
main方法执行完毕,销毁栈帧
程序正常退出
显示 "Hello World"
6.3 运行过程的五个阶段
| 1. 加载 | 类加载器读取.class文件的二进制数据,在内存中创建Class对象 | 遵循双亲委派模型 |
| 2. 链接-验证 | 检查字节码是否符合JVM规范,是否安全 | 防止恶意代码破坏JVM |
| 3. 链接-准备 | 为静态变量分配内存并设置默认初始值 | 如int初始化为0,引用类型初始化为null |
| 4. 链接-解析 | 将符号引用替换为直接引用 | 常量池中的符号转为内存地址 |
| 5. 初始化 | 执行静态初始化器和静态变量赋值 | 执行static{}块和静态字段赋值 |
| 6. 执行 | 找到main方法并逐条执行字节码指令 | 解释执行/JIT编译执行 |
6.4 JVM、JRE、JDK的关系回顾
#mermaid-svg-PvsFd0ELs1Zc3O6J{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-PvsFd0ELs1Zc3O6J .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-PvsFd0ELs1Zc3O6J .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-PvsFd0ELs1Zc3O6J .error-icon{fill:#552222;}#mermaid-svg-PvsFd0ELs1Zc3O6J .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-PvsFd0ELs1Zc3O6J .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-PvsFd0ELs1Zc3O6J .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-PvsFd0ELs1Zc3O6J .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-PvsFd0ELs1Zc3O6J .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-PvsFd0ELs1Zc3O6J .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-PvsFd0ELs1Zc3O6J .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-PvsFd0ELs1Zc3O6J .marker{fill:#333333;stroke:#333333;}#mermaid-svg-PvsFd0ELs1Zc3O6J .marker.cross{stroke:#333333;}#mermaid-svg-PvsFd0ELs1Zc3O6J svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-PvsFd0ELs1Zc3O6J p{margin:0;}#mermaid-svg-PvsFd0ELs1Zc3O6J .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-PvsFd0ELs1Zc3O6J .cluster-label text{fill:#333;}#mermaid-svg-PvsFd0ELs1Zc3O6J .cluster-label span{color:#333;}#mermaid-svg-PvsFd0ELs1Zc3O6J .cluster-label span p{background-color:transparent;}#mermaid-svg-PvsFd0ELs1Zc3O6J .label text,#mermaid-svg-PvsFd0ELs1Zc3O6J span{fill:#333;color:#333;}#mermaid-svg-PvsFd0ELs1Zc3O6J .node rect,#mermaid-svg-PvsFd0ELs1Zc3O6J .node circle,#mermaid-svg-PvsFd0ELs1Zc3O6J .node ellipse,#mermaid-svg-PvsFd0ELs1Zc3O6J .node polygon,#mermaid-svg-PvsFd0ELs1Zc3O6J .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-PvsFd0ELs1Zc3O6J .rough-node .label text,#mermaid-svg-PvsFd0ELs1Zc3O6J .node .label text,#mermaid-svg-PvsFd0ELs1Zc3O6J .image-shape .label,#mermaid-svg-PvsFd0ELs1Zc3O6J .icon-shape .label{text-anchor:middle;}#mermaid-svg-PvsFd0ELs1Zc3O6J .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-PvsFd0ELs1Zc3O6J .rough-node .label,#mermaid-svg-PvsFd0ELs1Zc3O6J .node .label,#mermaid-svg-PvsFd0ELs1Zc3O6J .image-shape .label,#mermaid-svg-PvsFd0ELs1Zc3O6J .icon-shape .label{text-align:center;}#mermaid-svg-PvsFd0ELs1Zc3O6J .node.clickable{cursor:pointer;}#mermaid-svg-PvsFd0ELs1Zc3O6J .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-PvsFd0ELs1Zc3O6J .arrowheadPath{fill:#333333;}#mermaid-svg-PvsFd0ELs1Zc3O6J .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-PvsFd0ELs1Zc3O6J .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-PvsFd0ELs1Zc3O6J .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-PvsFd0ELs1Zc3O6J .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-PvsFd0ELs1Zc3O6J .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-PvsFd0ELs1Zc3O6J .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-PvsFd0ELs1Zc3O6J .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-PvsFd0ELs1Zc3O6J .cluster text{fill:#333;}#mermaid-svg-PvsFd0ELs1Zc3O6J .cluster span{color:#333;}#mermaid-svg-PvsFd0ELs1Zc3O6J div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-PvsFd0ELs1Zc3O6J .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-PvsFd0ELs1Zc3O6J rect.text{fill:none;stroke-width:0;}#mermaid-svg-PvsFd0ELs1Zc3O6J .icon-shape,#mermaid-svg-PvsFd0ELs1Zc3O6J .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-PvsFd0ELs1Zc3O6J .icon-shape p,#mermaid-svg-PvsFd0ELs1Zc3O6J .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-PvsFd0ELs1Zc3O6J .icon-shape .label rect,#mermaid-svg-PvsFd0ELs1Zc3O6J .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-PvsFd0ELs1Zc3O6J .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-PvsFd0ELs1Zc3O6J .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-PvsFd0ELs1Zc3O6J :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
JDK(Java Development Kit)Java开发工具包
JRE(Java Runtime Environment)Java运行环境
JVM(Java Virtual Machine)Java虚拟机
类加载器
执行引擎
垃圾回收器
核心类库(rt.jar / 模块)
开发工具javac, java, jar, javadoc…
- JVM:执行字节码的虚拟计算机
- JRE:JVM + 核心类库(运行Java程序的最小环境)
- JDK:JRE + 开发工具(用于开发Java程序)
作为开发者,我们安装的是JDK;而最终用户只需要JRE(或一个内嵌JRE)来运行我们的程序。
七、完整的编译与执行流程图
将上述所有步骤串联起来,一个Java程序的完整生命周期如下:
#mermaid-svg-j8lVWnGbejAz9Ftp{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-j8lVWnGbejAz9Ftp .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-j8lVWnGbejAz9Ftp .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-j8lVWnGbejAz9Ftp .error-icon{fill:#552222;}#mermaid-svg-j8lVWnGbejAz9Ftp .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-j8lVWnGbejAz9Ftp .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-j8lVWnGbejAz9Ftp .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-j8lVWnGbejAz9Ftp .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-j8lVWnGbejAz9Ftp .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-j8lVWnGbejAz9Ftp .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-j8lVWnGbejAz9Ftp .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-j8lVWnGbejAz9Ftp .marker{fill:#333333;stroke:#333333;}#mermaid-svg-j8lVWnGbejAz9Ftp .marker.cross{stroke:#333333;}#mermaid-svg-j8lVWnGbejAz9Ftp svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-j8lVWnGbejAz9Ftp p{margin:0;}#mermaid-svg-j8lVWnGbejAz9Ftp .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-j8lVWnGbejAz9Ftp .cluster-label text{fill:#333;}#mermaid-svg-j8lVWnGbejAz9Ftp .cluster-label span{color:#333;}#mermaid-svg-j8lVWnGbejAz9Ftp .cluster-label span p{background-color:transparent;}#mermaid-svg-j8lVWnGbejAz9Ftp .label text,#mermaid-svg-j8lVWnGbejAz9Ftp span{fill:#333;color:#333;}#mermaid-svg-j8lVWnGbejAz9Ftp .node rect,#mermaid-svg-j8lVWnGbejAz9Ftp .node circle,#mermaid-svg-j8lVWnGbejAz9Ftp .node ellipse,#mermaid-svg-j8lVWnGbejAz9Ftp .node polygon,#mermaid-svg-j8lVWnGbejAz9Ftp .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-j8lVWnGbejAz9Ftp .rough-node .label text,#mermaid-svg-j8lVWnGbejAz9Ftp .node .label text,#mermaid-svg-j8lVWnGbejAz9Ftp .image-shape .label,#mermaid-svg-j8lVWnGbejAz9Ftp .icon-shape .label{text-anchor:middle;}#mermaid-svg-j8lVWnGbejAz9Ftp .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-j8lVWnGbejAz9Ftp .rough-node .label,#mermaid-svg-j8lVWnGbejAz9Ftp .node .label,#mermaid-svg-j8lVWnGbejAz9Ftp .image-shape .label,#mermaid-svg-j8lVWnGbejAz9Ftp .icon-shape .label{text-align:center;}#mermaid-svg-j8lVWnGbejAz9Ftp .node.clickable{cursor:pointer;}#mermaid-svg-j8lVWnGbejAz9Ftp .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-j8lVWnGbejAz9Ftp .arrowheadPath{fill:#333333;}#mermaid-svg-j8lVWnGbejAz9Ftp .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-j8lVWnGbejAz9Ftp .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-j8lVWnGbejAz9Ftp .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-j8lVWnGbejAz9Ftp .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-j8lVWnGbejAz9Ftp .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-j8lVWnGbejAz9Ftp .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-j8lVWnGbejAz9Ftp .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-j8lVWnGbejAz9Ftp .cluster text{fill:#333;}#mermaid-svg-j8lVWnGbejAz9Ftp .cluster span{color:#333;}#mermaid-svg-j8lVWnGbejAz9Ftp div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-j8lVWnGbejAz9Ftp .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-j8lVWnGbejAz9Ftp rect.text{fill:none;stroke-width:0;}#mermaid-svg-j8lVWnGbejAz9Ftp .icon-shape,#mermaid-svg-j8lVWnGbejAz9Ftp .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-j8lVWnGbejAz9Ftp .icon-shape p,#mermaid-svg-j8lVWnGbejAz9Ftp .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-j8lVWnGbejAz9Ftp .icon-shape .label rect,#mermaid-svg-j8lVWnGbejAz9Ftp .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-j8lVWnGbejAz9Ftp .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-j8lVWnGbejAz9Ftp .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-j8lVWnGbejAz9Ftp :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
失败(语法错误)
成功
1. 编辑编写 HelloWorld.java(文本编辑器/IDE)
2. 保存存储为 .java 文件(UTF-8编码)
3. 编译javac HelloWorld.java(javac编译器)
4. 编译是否成功?
修改源代码根据错误提示修正
5. 生成字节码HelloWorld.class
6. 运行java HelloWorld(java启动器)
7. JVM启动创建JVM实例
8. 类加载加载HelloWorld.class
9. 字节码验证
10. 类初始化
11. 执行main方法
12. 输出结果Hello World
13. 程序退出返回状态码0
八、常见错误与排查指南
初学者在第一次运行Java程序时,几乎必然会遇到各种错误。以下是最高频的错误及解决方案。
8.1 “javac 不是内部或外部命令”
C:\\> javac HelloWorld.java
'javac' 不是内部或外部命令,也不是可运行的程序或批处理文件。
原因:
- JDK未安装
- JDK安装后环境变量(PATH)未配置或配置错误
- 安装后未重新打开命令行窗口
解决步骤:
| 1 | 确认JDK已安装:检查C:\\Program Files\\Java\\下是否有JDK目录 |
| 2 | 找到JDK的bin目录路径,例如C:\\Program Files\\Java\\jdk-21\\bin |
| 3 | 将bin目录路径添加到系统环境变量PATH中 |
| 4 | 重新打开命令行窗口(已打开的窗口不会自动更新环境变量) |
| 5 | 再次执行javac -version验证 |
8.2 类名与文件名不匹配
C:\\> javac HelloWorld.java
HelloWorld.java:1: 错误: 类HelloWorld是公共的, 应在名为 HelloWorld.java 的文件中声明
public class HelloWorld {
^
1 个错误
原因: public类的类名与文件名不一致。例如文件名为hello.java,但类名为HelloWorld。
注意: 即使只是大小写不同(如helloworld.java与HelloWorld),也会导致编译失败,因为在某些文件系统(如Linux)中,大小写是敏感的。
8.3 找不到main方法
C:\\> java HelloWorld
错误: 在类 HelloWorld 中找不到 main 方法, 请将 main 方法定义为:
public static void main(String[] args)
最常见的main方法书写错误:
| public void main(String[] args) | 缺少static |
| public static void main(String args) | 参数应为数组而非单个String |
| public static void main() | 缺少参数列表 |
| public static int main(String[] args) | 返回类型应为void |
| public static void Main(String[] args) | 方法名大小写不对,应为main |
| public static void main(String[] args) | 这是在类外部定义的,必须写在类体内 |
正确的签名逐字符对照:
public static void main ( String [ ] args )
✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
8.4 语法错误:缺少分号
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World") // 缺少分号
}
}
编译报错:
HelloWorld.java:3: 错误: 需要';'
System.out.println("Hello World")
^
1 个错误
Java编译器会尽量指出缺少分号的位置,错误信息中的^符号指向的位置就是问题所在。
8.5 语法错误:字符串未闭合
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World); // 缺少右引号
}
}
8.6 语法错误:括号不匹配
Java中每个{必须有对应的}、每个(必须有对应的)。括号不匹配是初学者常犯的错误:
// 错误:缺少一个 }
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
// 缺少类的结束花括号
花括号配对技巧:先写一对括号,再在中间填充代码;使用IDE的括号高亮功能来辅助检查。
8.7 常见错误速查表
| javac: command not found | PATH未配置 | 检查环境变量 |
| 类XXX是公共的,应在XXX.java中声明 | 类名与文件名不匹配 | 确保两者一致 |
| 找不到main方法 | main方法签名错误 | 逐字符检查main方法 |
| 需要';' | 缺少分号 | 检查每条语句末尾 |
| 需要';' 且位置在一行开头 | 上一行缺少分号 | 检查前一条语句 |
| 非法的字符 | 使用了中文标点或不可见字符 | 检查引号、分号是否为英文符号 |
| 编码GBK的不可映射字符 | 文件编码问题(含中文注释时) | 用javac -encoding UTF-8编译 |
| 找不到或无法加载主类 | 类名写错或不在classpath中 | 检查类名拼写和大小写 |
| java.lang.NoClassDefFoundError | 运行时缺少依赖 | 不是HelloWorld程序的常见问题 |
九、使用文本编辑器 vs IDE
9.1 初级阶段:文本编辑器(推荐入门时使用)
使用记事本、VS Code、Sublime Text等文本编辑器来编写Java代码,有助于你深入理解编译过程。
| 记事本 | 系统自带,无任何辅助功能 | 体验最原始的编码过程 |
| Notepad++ | 轻量,支持语法高亮 | Windows平台入门首选 |
| VS Code | 功能丰富,插件生态好 | 跨平台,轻量级IDE |
| Sublime Text | 快速,简洁 | 轻量级开发 |
使用文本编辑器的优点:
- 深刻理解代码的每一个字符都是你自己写的
- 不会有IDE自动补全让你跳过思考
- 必须手动执行javac和java命令,理解编译流程
- 遇到错误时能更好地理解编译器报错信息
使用文本编辑器的缺点:
- 缺少代码提示,打字效率低
- 没有实时错误检查,需要编译才能发现错误
- 调试困难
9.2 进阶阶段:集成开发环境(IDE)
当你熟悉了基本语法后,可以切换到IDE来提升开发效率。
| IntelliJ IDEA | JetBrains | 功能最强大,智能提示出色,社区版免费 |
| Eclipse | Eclipse基金会 | 老牌IDE,免费开源,插件丰富 |
| NetBeans | Apache | 免费开源,对Java SE/EE支持良好 |
| VS Code + 插件 | Microsoft | 轻量灵活,通过插件实现IDE功能 |
9.3 建议的学习路径
#mermaid-svg-ieVK0knF4tYRRcYN{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ieVK0knF4tYRRcYN .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ieVK0knF4tYRRcYN .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ieVK0knF4tYRRcYN .error-icon{fill:#552222;}#mermaid-svg-ieVK0knF4tYRRcYN .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ieVK0knF4tYRRcYN .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ieVK0knF4tYRRcYN .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ieVK0knF4tYRRcYN .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ieVK0knF4tYRRcYN .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ieVK0knF4tYRRcYN .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ieVK0knF4tYRRcYN .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ieVK0knF4tYRRcYN .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ieVK0knF4tYRRcYN .marker.cross{stroke:#333333;}#mermaid-svg-ieVK0knF4tYRRcYN svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ieVK0knF4tYRRcYN p{margin:0;}#mermaid-svg-ieVK0knF4tYRRcYN .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-ieVK0knF4tYRRcYN .cluster-label text{fill:#333;}#mermaid-svg-ieVK0knF4tYRRcYN .cluster-label span{color:#333;}#mermaid-svg-ieVK0knF4tYRRcYN .cluster-label span p{background-color:transparent;}#mermaid-svg-ieVK0knF4tYRRcYN .label text,#mermaid-svg-ieVK0knF4tYRRcYN span{fill:#333;color:#333;}#mermaid-svg-ieVK0knF4tYRRcYN .node rect,#mermaid-svg-ieVK0knF4tYRRcYN .node circle,#mermaid-svg-ieVK0knF4tYRRcYN .node ellipse,#mermaid-svg-ieVK0knF4tYRRcYN .node polygon,#mermaid-svg-ieVK0knF4tYRRcYN .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ieVK0knF4tYRRcYN .rough-node .label text,#mermaid-svg-ieVK0knF4tYRRcYN .node .label text,#mermaid-svg-ieVK0knF4tYRRcYN .image-shape .label,#mermaid-svg-ieVK0knF4tYRRcYN .icon-shape .label{text-anchor:middle;}#mermaid-svg-ieVK0knF4tYRRcYN .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ieVK0knF4tYRRcYN .rough-node .label,#mermaid-svg-ieVK0knF4tYRRcYN .node .label,#mermaid-svg-ieVK0knF4tYRRcYN .image-shape .label,#mermaid-svg-ieVK0knF4tYRRcYN .icon-shape .label{text-align:center;}#mermaid-svg-ieVK0knF4tYRRcYN .node.clickable{cursor:pointer;}#mermaid-svg-ieVK0knF4tYRRcYN .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ieVK0knF4tYRRcYN .arrowheadPath{fill:#333333;}#mermaid-svg-ieVK0knF4tYRRcYN .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ieVK0knF4tYRRcYN .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ieVK0knF4tYRRcYN .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ieVK0knF4tYRRcYN .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ieVK0knF4tYRRcYN .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ieVK0knF4tYRRcYN .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ieVK0knF4tYRRcYN .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ieVK0knF4tYRRcYN .cluster text{fill:#333;}#mermaid-svg-ieVK0knF4tYRRcYN .cluster span{color:#333;}#mermaid-svg-ieVK0knF4tYRRcYN div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ieVK0knF4tYRRcYN .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ieVK0knF4tYRRcYN rect.text{fill:none;stroke-width:0;}#mermaid-svg-ieVK0knF4tYRRcYN .icon-shape,#mermaid-svg-ieVK0knF4tYRRcYN .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ieVK0knF4tYRRcYN .icon-shape p,#mermaid-svg-ieVK0knF4tYRRcYN .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ieVK0knF4tYRRcYN .icon-shape .label rect,#mermaid-svg-ieVK0knF4tYRRcYN .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ieVK0knF4tYRRcYN .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ieVK0knF4tYRRcYN .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ieVK0knF4tYRRcYN :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
手动编译运行理解底层流程
高效开发大型项目
前1-2周文本编辑器
第3-4周VS Code + 插件
第5周起IntelliJ IDEA
对于本系列后续文章,我们统一使用VS Code作为演示环境(兼顾轻量和功能),同时会给出通用的命令行指令。
十、从命令行高效操作(CMD/Terminal)
10.1 基本命令速查
| 查看当前目录 | cd 或 echo %cd% | pwd |
| 列出文件 | dir | ls -l |
| 切换目录 | cd 目录路径 | cd 目录路径 |
| 回到上级目录 | cd .. | cd .. |
| 创建目录 | mkdir 目录名 | mkdir 目录名 |
| 清屏 | cls | clear |
| 编译Java | javac HelloWorld.java | javac HelloWorld.java |
| 运行Java | java HelloWorld | java HelloWorld |
| 查看.java文件内容 | type HelloWorld.java | cat HelloWorld.java |
10.2 高效的命令行工作流程
一个典型的Java开发命令行操作序列:
# 1. 切换到工作目录
cd D:\\JavaProjects
# 2. 编辑代码(用你喜欢的编辑器)
notepad HelloWorld.java
# 3. 编译
javac HelloWorld.java
# 4. 如果有错误,修改后重新编译
javac HelloWorld.java
# 5. 运行
java HelloWorld
# 6. 可以用 && 将编译和运行串联(仅编译成功时才运行)
javac HelloWorld.java && java HelloWorld
10.3 处理中文编码问题
如果你在代码中使用了中文(如注释或字符串),编译时可能遇到编码错误:
# 指定UTF-8编码编译
javac -encoding UTF-8 HelloWorld.java
为了避免每次都要指定编码,建议将所有.java文件保存为UTF-8格式。在Windows记事本中,"另存为"时底部可以选择"UTF-8"编码。
十一、修改程序:动手实验
理论讲了一万遍,不如动手写一遍。下面我们尝试对这个最简单的程序进行各种修改,观察输出结果的变化。
11.1 打印中文
public class HelloWorld {
public static void main(String[] args) {
System.out.println("你好,世界!");
}
}
重新编译并运行:
javac -encoding UTF-8 HelloWorld.java
java HelloWorld
输出:
你好,世界!
这说明Java对Unicode有着良好的支持,可以直接输出中文字符。
11.2 打印多行内容
public class HelloWorld {
public static void main(String[] args) {
System.out.println("==================");
System.out.println(" 我的第一个Java程序");
System.out.println("==================");
System.out.println("Hello World");
System.out.println("你好,世界!");
}
}
输出:
==================
我的第一个Java程序
==================
Hello World
你好,世界!
11.3 使用print与println的对比
public class HelloWorld {
public static void main(String[] args) {
System.out.print("Hello ");
System.out.print("World");
System.out.println(); // 输出一个空行
System.out.println("—");
System.out.println("Hello");
System.out.println("World");
}
}
输出:
Hello World
—
Hello
World
11.4 使用转义序列
转义序列是以反斜杠\\开头的特殊字符组合,用于表示无法直接在代码中输入或需要特殊处理的字符。
| \\n | 换行(Newline) | U+000A |
| \\r | 回车(Carriage Return) | U+000D |
| \\t | 制表符(Tab) | U+0009 |
| \\\\ | 反斜杠本身 | U+005C |
| \\" | 双引号 | U+0022 |
| \\' | 单引号 | U+0027 |
示例:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("姓名\\t年龄\\t城市"); // \\t 制表符对齐
System.out.println("张三\\t20\\t北京");
System.out.println("李四\\t22\\t上海");
System.out.println(); // 空行
System.out.println("他说:\\"Java很有趣!\\""); // \\" 输出双引号
System.out.println(); // 空行
// \\n 在字符串中换行
System.out.println("第一行\\n第二行\\n第三行");
System.out.println(); // 空行
// 文件路径中的反斜杠需要转义
System.out.println("文件路径:D:\\\\JavaProjects\\\\HelloWorld.java");
}
}
输出:
姓名 年龄 城市
张三 20 北京
李四 22 上海
他说:"Java很有趣!"
第一行
第二行
第三行
文件路径:D:\\JavaProjects\\HelloWorld.java
11.5 使用命令行参数
public class HelloWorld {
public static void main(String[] args) {
System.out.println("接收到的命令行参数数量:" + args.length);
// 遍历并打印所有参数
for (int i = 0; i < args.length; i++) {
System.out.println("参数[" + i + "] = " + args[i]);
}
// 如果有至少一个参数,向第一个人问好
if (args.length > 0) {
System.out.println("你好," + args[0] + "!");
} else {
System.out.println("你好,陌生人!");
}
}
}
运行:
javac HelloWorld.java
java HelloWorld 张三 李四 王五
输出:
接收到的命令行参数数量:3
参数[0] = 张三
参数[1] = 李四
参数[2] = 王五
你好,张三!
注意: 这个例子中使用了for循环和if条件判断,这些内容会在后续文章中详细介绍。现在你只需要理解:args数组确实包含了命令行中传递给程序的所有参数。
11.6 输出数字与表达式
println可以直接输出数字以及表达式的结果:
public class HelloWorld {
public static void main(String[] args) {
System.out.println(2024);
System.out.println(3.1415926);
System.out.println(100 + 200); // 输出:300
System.out.println("100 + 200"); // 输出:100 + 200(字符串)
System.out.println("结果:" + 100 + 200); // 输出:结果:100200
System.out.println("结果:" + (100 + 200)); // 输出:结果:300
}
}
关键理解: +号在Java中既是加法运算符,也是字符串连接符。当+的任意一侧是字符串时,Java会将另一侧也转换为字符串然后拼接。使用括号()可以改变运算的优先级。
十二、深入理解main方法
12.1 main方法的完整契约
main方法是Java应用程序与JVM之间的"契约入口"。JVM要求这个接口必须严格遵守以下约定:
public static void main(String[] args)
Java语言规范(JLS 12.1.4)规定的main方法必须满足:
| 名称 | 必须为main |
| 访问修饰符 | 必须为public |
| 静态修饰符 | 必须为static |
| 返回类型 | 必须为void |
| 参数 | 必须为String[](String数组) |
12.2 main方法的几种合法变体
虽然上面是标准写法,但以下变体在语法上也是合法的:
// 1. 标准写法(推荐)
public static void main(String[] args)
// 2. 数组方括号放在参数名后面(等价)
public static void main(String args[])
// 3. 使用可变参数(Java 5+,等价于数组)
public static void main(String... args)
// 4. 参数名可以自定义
public static void main(String[] arguments)
public static void main(String[] params)
建议: 始终使用最标准的写法public static void main(String[] args)。在面试中要求手写main方法时,也请使用标准写法。这不是为了死板,而是为了保证代码的可读性和一致性。
12.3 main方法与程序生命周期
#mermaid-svg-oFYOmIfCwkq9QP47{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-oFYOmIfCwkq9QP47 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-oFYOmIfCwkq9QP47 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-oFYOmIfCwkq9QP47 .error-icon{fill:#552222;}#mermaid-svg-oFYOmIfCwkq9QP47 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-oFYOmIfCwkq9QP47 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-oFYOmIfCwkq9QP47 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-oFYOmIfCwkq9QP47 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-oFYOmIfCwkq9QP47 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-oFYOmIfCwkq9QP47 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-oFYOmIfCwkq9QP47 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-oFYOmIfCwkq9QP47 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-oFYOmIfCwkq9QP47 .marker.cross{stroke:#333333;}#mermaid-svg-oFYOmIfCwkq9QP47 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-oFYOmIfCwkq9QP47 p{margin:0;}#mermaid-svg-oFYOmIfCwkq9QP47 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-oFYOmIfCwkq9QP47 .cluster-label text{fill:#333;}#mermaid-svg-oFYOmIfCwkq9QP47 .cluster-label span{color:#333;}#mermaid-svg-oFYOmIfCwkq9QP47 .cluster-label span p{background-color:transparent;}#mermaid-svg-oFYOmIfCwkq9QP47 .label text,#mermaid-svg-oFYOmIfCwkq9QP47 span{fill:#333;color:#333;}#mermaid-svg-oFYOmIfCwkq9QP47 .node rect,#mermaid-svg-oFYOmIfCwkq9QP47 .node circle,#mermaid-svg-oFYOmIfCwkq9QP47 .node ellipse,#mermaid-svg-oFYOmIfCwkq9QP47 .node polygon,#mermaid-svg-oFYOmIfCwkq9QP47 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-oFYOmIfCwkq9QP47 .rough-node .label text,#mermaid-svg-oFYOmIfCwkq9QP47 .node .label text,#mermaid-svg-oFYOmIfCwkq9QP47 .image-shape .label,#mermaid-svg-oFYOmIfCwkq9QP47 .icon-shape .label{text-anchor:middle;}#mermaid-svg-oFYOmIfCwkq9QP47 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-oFYOmIfCwkq9QP47 .rough-node .label,#mermaid-svg-oFYOmIfCwkq9QP47 .node .label,#mermaid-svg-oFYOmIfCwkq9QP47 .image-shape .label,#mermaid-svg-oFYOmIfCwkq9QP47 .icon-shape .label{text-align:center;}#mermaid-svg-oFYOmIfCwkq9QP47 .node.clickable{cursor:pointer;}#mermaid-svg-oFYOmIfCwkq9QP47 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-oFYOmIfCwkq9QP47 .arrowheadPath{fill:#333333;}#mermaid-svg-oFYOmIfCwkq9QP47 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-oFYOmIfCwkq9QP47 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-oFYOmIfCwkq9QP47 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-oFYOmIfCwkq9QP47 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-oFYOmIfCwkq9QP47 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-oFYOmIfCwkq9QP47 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-oFYOmIfCwkq9QP47 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-oFYOmIfCwkq9QP47 .cluster text{fill:#333;}#mermaid-svg-oFYOmIfCwkq9QP47 .cluster span{color:#333;}#mermaid-svg-oFYOmIfCwkq9QP47 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-oFYOmIfCwkq9QP47 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-oFYOmIfCwkq9QP47 rect.text{fill:none;stroke-width:0;}#mermaid-svg-oFYOmIfCwkq9QP47 .icon-shape,#mermaid-svg-oFYOmIfCwkq9QP47 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-oFYOmIfCwkq9QP47 .icon-shape p,#mermaid-svg-oFYOmIfCwkq9QP47 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-oFYOmIfCwkq9QP47 .icon-shape .label rect,#mermaid-svg-oFYOmIfCwkq9QP47 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-oFYOmIfCwkq9QP47 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-oFYOmIfCwkq9QP47 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-oFYOmIfCwkq9QP47 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
否
是
JVM启动
查找main方法
找到main?
抛出NoSuchMethodError程序终止
准备main方法调用
调用main(args)
执行main方法体中的代码
main方法返回
JVM清理资源
JVM退出返回状态码
main方法的执行过程就是整个程序的生命周期:
十三、Java的命名规范与大小写敏感性
13.1 严格区分大小写
Java是一门严格区分大小写(Case-Sensitive)的语言。这意味着:
// 以下是四个完全不同的标识符
helloworld
HelloWorld
HELLOWORLD
helloWorld
这种严格区分贯穿整个Java语言:
| 类名 | HelloWorld vs helloworld | 不同的类 |
| 方法名 | main vs Main | 不同的方法 |
| 变量名 | count vs Count | 不同的变量 |
| 关键字 | class vs Class | 前者是关键字,后者是类名 |
| 文件名 | HelloWorld.java vs helloworld.java | 不同的文件(在区分大小写的文件系统上) |
13.2 public类名必须与文件名一致
这是Java语言规范的一条硬性规则:如果一个类被声明为public,那么包含该类的源文件名必须与该类名完全一致(包括大小写),并以.java结尾。
#mermaid-svg-zKrwMLUQ6b8cjcgt{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-zKrwMLUQ6b8cjcgt .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-zKrwMLUQ6b8cjcgt .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-zKrwMLUQ6b8cjcgt .error-icon{fill:#552222;}#mermaid-svg-zKrwMLUQ6b8cjcgt .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-zKrwMLUQ6b8cjcgt .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-zKrwMLUQ6b8cjcgt .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-zKrwMLUQ6b8cjcgt .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-zKrwMLUQ6b8cjcgt .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-zKrwMLUQ6b8cjcgt .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-zKrwMLUQ6b8cjcgt .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-zKrwMLUQ6b8cjcgt .marker{fill:#333333;stroke:#333333;}#mermaid-svg-zKrwMLUQ6b8cjcgt .marker.cross{stroke:#333333;}#mermaid-svg-zKrwMLUQ6b8cjcgt svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-zKrwMLUQ6b8cjcgt p{margin:0;}#mermaid-svg-zKrwMLUQ6b8cjcgt .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-zKrwMLUQ6b8cjcgt .cluster-label text{fill:#333;}#mermaid-svg-zKrwMLUQ6b8cjcgt .cluster-label span{color:#333;}#mermaid-svg-zKrwMLUQ6b8cjcgt .cluster-label span p{background-color:transparent;}#mermaid-svg-zKrwMLUQ6b8cjcgt .label text,#mermaid-svg-zKrwMLUQ6b8cjcgt span{fill:#333;color:#333;}#mermaid-svg-zKrwMLUQ6b8cjcgt .node rect,#mermaid-svg-zKrwMLUQ6b8cjcgt .node circle,#mermaid-svg-zKrwMLUQ6b8cjcgt .node ellipse,#mermaid-svg-zKrwMLUQ6b8cjcgt .node polygon,#mermaid-svg-zKrwMLUQ6b8cjcgt .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-zKrwMLUQ6b8cjcgt .rough-node .label text,#mermaid-svg-zKrwMLUQ6b8cjcgt .node .label text,#mermaid-svg-zKrwMLUQ6b8cjcgt .image-shape .label,#mermaid-svg-zKrwMLUQ6b8cjcgt .icon-shape .label{text-anchor:middle;}#mermaid-svg-zKrwMLUQ6b8cjcgt .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-zKrwMLUQ6b8cjcgt .rough-node .label,#mermaid-svg-zKrwMLUQ6b8cjcgt .node .label,#mermaid-svg-zKrwMLUQ6b8cjcgt .image-shape .label,#mermaid-svg-zKrwMLUQ6b8cjcgt .icon-shape .label{text-align:center;}#mermaid-svg-zKrwMLUQ6b8cjcgt .node.clickable{cursor:pointer;}#mermaid-svg-zKrwMLUQ6b8cjcgt .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-zKrwMLUQ6b8cjcgt .arrowheadPath{fill:#333333;}#mermaid-svg-zKrwMLUQ6b8cjcgt .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-zKrwMLUQ6b8cjcgt .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-zKrwMLUQ6b8cjcgt .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zKrwMLUQ6b8cjcgt .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-zKrwMLUQ6b8cjcgt .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zKrwMLUQ6b8cjcgt .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-zKrwMLUQ6b8cjcgt .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-zKrwMLUQ6b8cjcgt .cluster text{fill:#333;}#mermaid-svg-zKrwMLUQ6b8cjcgt .cluster span{color:#333;}#mermaid-svg-zKrwMLUQ6b8cjcgt div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-zKrwMLUQ6b8cjcgt .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-zKrwMLUQ6b8cjcgt rect.text{fill:none;stroke-width:0;}#mermaid-svg-zKrwMLUQ6b8cjcgt .icon-shape,#mermaid-svg-zKrwMLUQ6b8cjcgt .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-zKrwMLUQ6b8cjcgt .icon-shape p,#mermaid-svg-zKrwMLUQ6b8cjcgt .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-zKrwMLUQ6b8cjcgt .icon-shape .label rect,#mermaid-svg-zKrwMLUQ6b8cjcgt .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-zKrwMLUQ6b8cjcgt .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-zKrwMLUQ6b8cjcgt .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-zKrwMLUQ6b8cjcgt :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
错误!
错误!
文件: HelloWorld.java
public class HelloWorld
文件: MyApp.java
public class MyApp
文件: test.java
public class HelloWorld
文件: HelloWorld.java
public class helloworld
这条规则的原因在于:Java编译器和JVM需要通过文件名快速定位到public类,而不需要扫描文件内容。当其他类需要导入HelloWorld类时,编译器会自动查找HelloWorld.java或HelloWorld.class文件。
如果源文件中没有public类(所有类都是默认访问级别),则文件名可以是任意的。但通常我们会将主类声明为public。
13.3 Java命名规范总结
| 类名 | PascalCase(大驼峰) | HelloWorld, StudentManager, BufferedReader |
| 方法名 | camelCase(小驼峰) | main, toString, getStudentName |
| 变量名 | camelCase(小驼峰) | count, studentName, maxValue |
| 常量名 | UPPER_SNAKE_CASE | MAX_VALUE, PI, DEFAULT_PORT |
| 包名 | 全小写,点分隔 | com.example.myapp, java.util |
十四、HelloWorld的跨语言对比
使用Hello World程序来对比不同编程语言的语法,是理解语言差异的最佳方式之一。下面是一些主流语言的Hello World实现:
| Java | public class HelloWorld {public static void main(String[] a){System.out.println("Hello World");}} | 需要类,需要main方法,面向对象 |
| C | #include <stdio.h>int main() {printf("Hello World\\n");return 0;} | 需要头文件,面向过程 |
| C++ | #include <iostream>int main() {std::cout << "Hello World" << std::endl;return 0;} | 流式输出,面向对象+过程 |
| Python | print("Hello World") | 极简语法,解释型 |
| JavaScript | console.log("Hello World"); | 动态类型,浏览器/Node.js运行 |
| Go | package mainimport "fmt"func main() {fmt.Println("Hello World")} | 编译型,语法简洁 |
| Kotlin | fun main() {println("Hello World")} | 更简洁的JVM语言 |
| Rust | fn main() {println!("Hello World");} | 宏语法,系统级安全 |
从对比中可以明显看出,Java的Hello World程序相对冗长——这是Java面向对象设计的直接体现。即使是最简单的程序,也必须遵守"一切皆类"的原则。这种"冗长"在初学者看来是一种负担,但在大型项目开发中,它带来了更好的组织结构、更强的类型安全和更高的可维护性。
十五、动手实践:从零开始完整演练
下面,我们将完成一次完整的、没有任何跳步的实操演练。请跟着以下步骤操作。
步骤1:创建目录
# Windows
mkdir D:\\JavaProjects
cd D:\\JavaProjects
# macOS / Linux
mkdir ~/JavaProjects
cd ~/JavaProjects
步骤2:创建并编辑文件
用记事本(或任何文本编辑器)创建文件,确保文件名为HelloWorld.java。
对于Windows记事本用户,务必注意:
步骤3:输入代码
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
System.out.println("这是我的第一个Java程序。");
System.out.println("编译运行成功!");
}
}
步骤4:打开命令行
- Windows:按Win + R,输入cmd回车
- macOS:按Command + 空格,输入Terminal回车
- Linux:按Ctrl + Alt + T
步骤5:切换到工作目录
# Windows
cd /d D:\\JavaProjects
# macOS / Linux
cd ~/JavaProjects
步骤6:确认文件存在
# Windows
dir HelloWorld.java
# macOS / Linux
ls -l HelloWorld.java
确保能看到HelloWorld.java文件。
步骤7:编译
javac HelloWorld.java
如果没有任何错误信息输出,说明编译成功。此时目录下应该出现了HelloWorld.class。
# 确认.class文件已生成
dir HelloWorld.* # Windows
ls -l HelloWorld.* # macOS / Linux
步骤8:运行
java HelloWorld
预期输出:
Hello World!
这是我的第一个Java程序。
编译运行成功!
步骤9:庆祝
恭喜!你已经成功编写、编译并运行了你的第一个Java程序。虽然这只是万里长征的第一步,但它意味着你已经在Java学习的道路上正式启程了。
本章关键词回顾
| 源文件 | Source File | 以.java为后缀,包含Java源代码的文本文件 |
| 字节码文件 | Bytecode File | 以.class为后缀,编译器输出的中间代码文件 |
| 编译 | Compile | 将源代码转换为字节码的过程,使用javac命令 |
| 运行 | Run / Execute | JVM加载并执行字节码的过程,使用java命令 |
| 类 | Class | Java程序的基本组织单元,使用class关键字定义 |
| 访问修饰符 | Access Modifier | 控制类/方法/字段的可见性,如public |
| 静态方法 | Static Method | 属于类本身而非实例的方法,使用static修饰 |
| 返回类型 | Return Type | 方法返回值的数据类型,void表示无返回值 |
| main方法 | main Method | Java程序的入口方法,JVM自动调用 |
| 参数列表 | Parameter List | 方法接收的输入参数声明 |
| 字符串 | String | 表示文本数据的数据类型 |
| 数组 | Array | 存储多个同类型元素的容器,使用[]表示 |
| 标准输出 | Standard Output | 默认输出目标(控制台),通过System.out访问 |
| 换行输出 | println | 输出内容后自动换行的方法 |
| 转义序列 | Escape Sequence | 以\\开头的特殊字符表示法,如\\n表示换行 |
| 命名规范 | Naming Convention | 类名PascalCase,方法名camelCase等约定 |
| 大小写敏感 | Case-Sensitive | Java中大小写字母被视为不同的字符 |
| JVM | Java Virtual Machine | Java虚拟机,执行字节码的运行时环境 |
| JRE | Java Runtime Environment | JVM + 核心类库,运行Java程序所需 |
| JDK | Java Development Kit | JRE + 开发工具,开发Java程序所需 |
| 命令行参数 | Command-Line Argument | 运行程序时传递给main方法的数据 |
思考与练习
基础练习
手写HelloWorld:不参照任何资料,从零开始手写出完整的HelloWorld程序,并通过编译运行。重复3-5次,直到能不经思考地写出。
排查错误:故意在代码中制造以下错误,观察编译器的报错信息,理解每种错误的含义:
- 删除public关键字
- 删除static关键字
- 将main改成Main
- 删除参数String[] args
- 删除语句末尾的分号
- 将类名改为hello但文件名保持HelloWorld.java
扩展输出:修改程序,使其输出以下内容(使用转义序列):
姓名:张三
年龄:20
城市:北京
兴趣爱好:"编程"、"篮球"、"阅读"
命令行参数:编写程序,接收两个命令行参数(姓名和城市),输出格式如:你好,[姓名]!欢迎来到[城市]。
进阶思考
探究题:使用javap -c命令查看编译后的字节码,尝试理解每一条指令的含义。你发现了哪些源代码中没有体现的内容?
对比实验:分别在Windows记事本、VS Code、IntelliJ IDEA中编写并运行同一个HelloWorld程序,记录各自的步骤差异和体验差异。
研究题:Java为什么设计为"先编译后解释执行"(编译为字节码再由JVM执行),而不是像C语言那样直接编译为机器码,或像Python那样直接解释执行?这种设计带来了哪些优势?
拓展阅读:查看JDK源码中System类和PrintStream类的文档(在JDK安装目录的lib/src.zip中或在线Java API文档),了解它们还提供了哪些功能。
下一篇文章预告: 第11章:Java基础语法——数据类型与变量声明详解
编者寄语: 每一个Java高手都曾在这个简单的HelloWorld面前屏息等待过。不要因为程序的简单而轻视它——它包含了Java程序最基本的骨架结构。把这个骨架刻在脑海里,之后的每一行代码,都将在这个骨架之上添砖加瓦。学习编程,最重要的不是"看懂",而是"动手做"。现在,打开你的编辑器,写下属于你的HelloWorld吧。


