在编程学习中,有一个延续了半个多世纪的传统------用"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"这个示例程序推向了全世界。
c
// 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),执行以下命令:
bash
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)
再验证编译器是否可用:
bash
javac -version
预期输出:
javac 21.0.1
两条命令都能正常输出版本号,说明你的Java环境已经准备就绪。下面我们正式开始编写代码。
三、创建第一个Java源文件
3.1 选择工作目录
首先,在电脑上创建一个专门存放Java代码的文件夹。建议在D盘(或你常用的盘符)根目录下创建:
bash
# 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文件,输入以下代码:
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
这个参数的作用是接收命令行参数。当你在命令行中这样运行程序:
bash
java HelloWorld 张三 李四 王五
那么args数组的内容就是:
java
args[0] = "张三"
args[1] = "李四"
args[2] = "王五"
关于String数组的声明,Java支持两种等价的写法:
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"的缩写。
java
// println:输出后换行
System.out.println("第一行");
System.out.println("第二行");
// 输出:
// 第一行
// 第二行
// print:输出后不换行
System.out.print("Hello ");
System.out.print("World");
// 输出:
// Hello World
println方法有多个重载版本,可以接受不同类型的参数:
java
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中字符串必须使用双引号,单引号用于单个字符:
java
"Hello World" // 字符串,正确 ✓
"你好世界" // 中文字符串,也可以 ✓
'H' // 单个字符,正确 ✓
'Hello World' // 错误!不能用单引号包裹多个字符 ✗
4.4.5 ; ------ 语句结束符
分号;标志着一条Java语句的结束。在Java中,几乎每一条执行指令都必须以分号结尾。这与Python等语言不同------Python用换行来分隔语句,而Java用分号。
遗漏分号是初学者最容易犯的错误之一:
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所在的目录,执行编译命令:
bash
javac HelloWorld.java
注意:
- 命令是
javac(java compiler),不是java - 文件名必须包含
.java扩展名 - 文件名大小写必须与实际文件完全一致
- 如果路径中包含空格,需要用双引号包裹整个路径
编译成功的标志是:没有任何输出信息 。在命令行世界中,没有消息就是好消息。编译成功后,你会在同一目录下发现一个新文件:HelloWorld.class。
bash
# 查看编译结果
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实际执行的指令:
bash
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命令来运行程序:
bash
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;} 失败(语法错误)
成功
- 编辑
编写 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 不是内部或外部命令"
bash
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 类名与文件名不匹配
bash
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方法
bash
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 语法错误:缺少分号
java
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 语法错误:字符串未闭合
java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World); // 缺少右引号
}
}
8.6 语法错误:括号不匹配
Java中每个{必须有对应的}、每个(必须有对应的)。括号不匹配是初学者常犯的错误:
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来提升开发效率。
| 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 基本命令速查
| 操作 | Windows (CMD) | macOS / Linux (Terminal) |
|---|---|---|
| 查看当前目录 | 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开发命令行操作序列:
bash
# 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 处理中文编码问题
如果你在代码中使用了中文(如注释或字符串),编译时可能遇到编码错误:
bash
# 指定UTF-8编码编译
javac -encoding UTF-8 HelloWorld.java
为了避免每次都要指定编码,建议将所有.java文件保存为UTF-8格式。在Windows记事本中,"另存为"时底部可以选择"UTF-8"编码。
十一、修改程序:动手实验
理论讲了一万遍,不如动手写一遍。下面我们尝试对这个最简单的程序进行各种修改,观察输出结果的变化。
11.1 打印中文
java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("你好,世界!");
}
}
重新编译并运行:
bash
javac -encoding UTF-8 HelloWorld.java
java HelloWorld
输出:
你好,世界!
这说明Java对Unicode有着良好的支持,可以直接输出中文字符。
11.2 打印多行内容
java
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的对比
java
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 使用转义序列
转义序列是以反斜杠\开头的特殊字符组合,用于表示无法直接在代码中输入或需要特殊处理的字符。
| 转义序列 | 含义 | Unicode值 |
|---|---|---|
\n |
换行(Newline) | U+000A |
\r |
回车(Carriage Return) | U+000D |
\t |
制表符(Tab) | U+0009 |
\\ |
反斜杠本身 | U+005C |
\" |
双引号 | U+0022 |
\' |
单引号 | U+0027 |
示例:
java
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 使用命令行参数
java
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("你好,陌生人!");
}
}
}
运行:
bash
javac HelloWorld.java
java HelloWorld 张三 李四 王五
输出:
接收到的命令行参数数量:3
参数[0] = 张三
参数[1] = 李四
参数[2] = 王五
你好,张三!
注意: 这个例子中使用了
for循环和if条件判断,这些内容会在后续文章中详细介绍。现在你只需要理解:args数组确实包含了命令行中传递给程序的所有参数。
11.6 输出数字与表达式
println可以直接输出数字以及表达式的结果:
java
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要求这个接口必须严格遵守以下约定:
java
public static void main(String[] args)
Java语言规范(JLS 12.1.4)规定的main方法必须满足:
| 要求 | 说明 |
|---|---|
| 名称 | 必须为main |
| 访问修饰符 | 必须为public |
| 静态修饰符 | 必须为static |
| 返回类型 | 必须为void |
| 参数 | 必须为String[](String数组) |
12.2 main方法的几种合法变体
虽然上面是标准写法,但以下变体在语法上也是合法的:
java
// 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方法的执行过程就是整个程序的生命周期:
- JVM启动后查找main方法
- 为main方法创建调用环境(包括准备String\[\]参数)
- 调用main方法,程序控制权交给你的代码
- main方法执行完毕(或调用
System.exit()提前退出) - JVM回收资源并退出
十三、Java的命名规范与大小写敏感性
13.1 严格区分大小写
Java是一门严格区分大小写(Case-Sensitive)的语言。这意味着:
java
// 以下是四个完全不同的标识符
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 main import "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:创建目录
bash
# Windows
mkdir D:\JavaProjects
cd D:\JavaProjects
# macOS / Linux
mkdir ~/JavaProjects
cd ~/JavaProjects
步骤2:创建并编辑文件
用记事本(或任何文本编辑器)创建文件,确保文件名为HelloWorld.java。
对于Windows记事本用户,务必注意:
- 打开记事本
- 输入代码
- 点击"文件" -> "另存为"
- 在"文件名"输入框中输入:
"HelloWorld.java"(带英文双引号,强制使用该文件名和扩展名) - "保存类型"选择:
所有文件 (*.*) - "编码"选择:
UTF-8 - 点击保存
步骤3:输入代码
java
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:切换到工作目录
bash
# Windows
cd /d D:\JavaProjects
# macOS / Linux
cd ~/JavaProjects
步骤6:确认文件存在
bash
# Windows
dir HelloWorld.java
# macOS / Linux
ls -l HelloWorld.java
确保能看到HelloWorld.java文件。
步骤7:编译
bash
javac HelloWorld.java
如果没有任何错误信息输出,说明编译成功。此时目录下应该出现了HelloWorld.class。
bash
# 确认.class文件已生成
dir HelloWorld.* # Windows
ls -l HelloWorld.* # macOS / Linux
步骤8:运行
bash
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吧。