第6章 第一个 Java 程序与代码结构
12 分钟阅读
第六章 第一个 Java 程序与代码结构
“Talk is cheap, show me the code.” — 这句话在 Java 世界里尤其正确。再多理论也比不上亲手跑通一个程序带来的成就感。准备好了吗?让我们从那句经典的
Hello World开始,正式踏入 Java 的大门。
6.1 Hello World 完整解析——逐行讲解每一句代码
让我们先来看一个完整可运行的 Java 程序,然后像拆解精密机械一样,一行一行地剖析它。
| |
把它保存为 HelloWorld.java,然后在命令行执行:
| |
输出结果:
Hello World
恭喜!你刚刚完成了一个 Java 程序的编译和运行。不过,你真的理解每一行代码的含义了吗?让我们继续往下拆解。
6.1.1 public class HelloWorld { } 是什么意思?
这一行声明了一个类(class)。类是什么?你可以把它想象成一个"容器",用来装代码。在 Java 的世界里,一切皆为对象,而类就是对象的蓝图(blueprint)。
public:这是访问修饰符(access modifier),表示这个类是"公开的",谁都可以用。没有这个关键字的话,类就只能被同包的代码访问。class:关键字,告诉编译器"我要定义一个类"。HelloWorld:类的名字。这个名字可不是随便起的——Java 规定,类名必须和文件名一致,否则编译会报错(关于这条规则,我们会在 6.2.2 节详细说)。
所以,public class HelloWorld { } 的意思是:“我要定义一个公开的类,名字叫 HelloWorld,它的内容用一对花括号包裹。”
💡 类命名规范:类名采用 PascalCase 风格,即每个单词的首字母大写,如
HelloWorld、MyFirstProgram、AccountService。
6.1.2 public static void main(String[] args) { } 每一部分的作用
这一行是整个 Java 程序的入口(entry point)。程序运行时,JVM(Java 虚拟机)会从 main 方法开始执行。没有 main 方法?程序根本不知道该从哪里开始!
让我们逐个拆解这行代码的每个组成部分:
| |
| 组成部分 | 含义 | 作用 |
|---|---|---|
public | 访问修饰符 | 告诉 JVM,这个方法任何代码都可以调用 |
static | 静态关键字 | 表示这个方法属于类本身,而不是某个对象;JVM 可以直接通过类名调用,无需先创建对象 |
void | 返回类型 | 表示这个方法执行完毕后不返回任何值 |
main | 方法名 | JVM 规定死了的名字,必须是 main |
String[] args | 参数 | 接收命令行传入的字符串数组 |
💡 为什么
main必须是static? 因为 JVM 在启动程序时,还没有创建任何对象。如果main不是静态的,JVM 就得先实例化一个对象才能调用main——但这本身就需要先执行main!这是一个"先有鸡还是先有蛋"的问题。static关键字打破了这一僵局,让 JVM 可以在不创建对象的情况下直接运行代码。
6.1.3 System.out.println("Hello World"); 怎么工作的?
这行代码干了一件核心的事:在屏幕上打印一行文字。
我们来分解它:
System.out.println("Hello World");
System:Java 标准库提供的类,代表系统运行环境。.(点操作符):用来访问对象(或类)内部的属性和方法。out:System 类的一个静态属性,它是一个输出流对象,指向标准输出(通常是你的屏幕)。println:这个方法的名字是 “print line” 的缩写,意思是"打印这一行"。每调用一次,会在输出后面加一个换行符(\n),这样下一次打印会从新的一行开始。"Hello World":要打印的字符串内容,用双引号包裹。引号内的内容会原样输出,不会被当作代码处理。
如果你不想换行,可以用 print(没有 ln):
| |
输出:Hello World(不换行,两个词连在一起)
💡 还有
printf? 是的,类似 C 语言的格式化输出:System.out.printf("我的名字是 %s,年龄是 %d%n", "张三", 25);其中%s表示字符串占位符,%d表示整数占位符,%n是跨平台的换行符(在 Windows 上输出\r\n,在 Linux/Mac 上输出\n)。
6.1.4 args 参数是干什么的?
String[] args 是 main 方法接收外部参数的入口。
当你从命令行运行程序时,可以附加一些额外的信息:
| |
这些信息(Alice 和 2024)会被当作字符串数组存入 args 参数中。
| |
运行 java CommandLineDemo Alice 2024,输出:
第 0 个参数: Alice
第 1 个参数: 2024
💡 小技巧:
args这个名字是可以改的,比如String[] arguments或者String[] argv,但args是 Java 社区约定俗成的惯例。参数名字无关紧要,关键是它的类型String[]。
6.2 Java 代码的基本规则——这些规则必须遵守
Java 是一门"强规则"语言。编译器(compiler)是一个极度较真的裁判——你少写一个分号,它就罢工;你大小写写错了,它就报错。理解这些规则,是写好 Java 代码的第一步。
6.2.1 Java 是大小写敏感的语言——String 和 string 不一样!
Java 对大小写极其敏感。这意味着:
String是一个合法的类名(Java 标准库中的字符串类)string编译器压根不认识,会报cannot find symbol错误System和system是完全不同的东西
| |
⚠️ 新手最容易踩的坑之一:很多语言对大小写比较宽容(比如 PHP、JavaScript 的某些场景),但 Java 不一样。变量名、方法名、类名,每一个字符的大小写都要写对。建议在写代码时开启 IDE(集成开发环境,如 IntelliJ IDEA 或 VS Code)的实时错误提示,能帮你第一时间发现这类问题。
6.2.2 类名必须和文件名一致——HelloWorld.java
在 Java 中,如果一个类是 public(公开的),它必须保存在与类名同名的文件中。
- 类名
HelloWorld→ 文件名HelloWorld.java - 类名
MyFirstProgram→ 文件名MyFirstProgram.java
| |
如果文件名和类名不匹配,编译直接报错:
| |
💡 那一个 .java 文件里可以有多个类吗? 可以!但至多只能有一个
public类,且public类的名字必须和文件名一致。其他非public的类可以随意命名(虽然不推荐)。详细内容见 6.2.5 节。
6.2.3 每条语句以分号结尾——忘了分号会怎样?
在 Java 中,几乎所有的语句都必须以分号(;)结尾。分号是编译器的"句子结束标志",告诉它"这句话说完了"。
| |
漏写分号是最常见的初学者错误之一。好消息是,IDE 会用红色波浪线标出这类错误,一目了然。
💡 例外情况:方法声明、条件语句、循环语句等结构化语句的结尾不需要分号,因为它们以
{ }结束。但这些结构内部的具体操作语句仍然需要分号。
6.2.4 代码块用花括号 { } 包裹——Python 用缩进,Java 用括号
Java 使用花括号 {} 来划分代码块(code block),而不是依赖缩进。
| |
对比 Python(使用缩进):
| |
💡 两种风格各有优劣:Java 的
{}风格更显式,即使代码缩进乱了,逻辑结构依然清晰;Python 的缩进风格更简洁,但一旦缩进出错,程序逻辑就乱了。无论哪种风格,保持一致的缩进都是良好编程习惯。
6.2.5 一个 .java 文件可以有多个类——但 public 类只能有一个
Java 允许在一个 .java 文件中定义多个类,但这背后有一套规则:
| |
规则总结:
| 条件 | 规则 |
|---|---|
public 类 | 最多只能有一个,且文件名必须与此类名一致 |
非 public 类 | 可以有任意多个,类名不需要和文件名一致 |
public 类 | 整个包(package)内可见 |
非 public 类 | 仅在同一文件内可见(类似"文件私有"的含义) |
💡 实际建议:虽然在技术上允许,但强烈不推荐在一个文件中放多个类。这会让代码难以维护,降低可读性。最佳实践是:一个
.java文件,一个public类,类名即文件名。
6.2.6 Java 的入口是 main 方法
当你在命令行输入 java HelloWorld 时,JVM 会启动,查找 HelloWorld 类中签名为以下的方法:
| |
然后从这一行开始执行代码。没有 main 方法,程序无法独立运行(除非通过其他方式调用,比如单元测试框架,但那属于特例)。
⚠️ 注意:
main方法的签名必须完全一致,包括大小写、String而非string、args变量名可改但类型不能变。以下都是错误的:
public static void Main(String[] args)—Main不是main,JVM 不认public void main(String[] args)— 缺少static,JVM 找不到入口public static void main()— 缺少参数String[] args,不匹配
6.3 Java 注释的写法——给自己和同伴留的便签
代码是写给人看的,顺便给机器执行。注释(comment)是你留给未来自己和其他开发者的便签——提醒"这里为什么这么做"。
6.3.1 单行注释:// 这里写注释
用双斜杠 // 开头的注释,只对当前行有效。
| |
💡 快捷键:在 IntelliJ IDEA / Android Studio 中,选中一行或多行代码,按
Ctrl + /可以快速添加或移除单行注释。
6.3.2 多行注释:/* 多行注释 */
用 /* 开始,用 */ 结束,中间可以跨越多行。
| |
💡 IDE 自动补全:输入
/*后按回车,很多 IDE 会自动补上*并换行,让你的多行注释看起来整齐美观。
6.3.3 文档注释:/** 这是文档注释,可以生成 API 文档 */
以 /** 开头的是文档注释(Javadoc),这是 Java 特有的注释格式。工具可以提取这种注释,生成 API 文档网页。
| |
💡 Javadoc 生成:在命令行运行
javadoc YourClass.java,就会生成一份 HTML 格式的 API 文档(当然,实际项目中通常用 Maven/Gradle 的插件自动生成)。
6.3.4 好的注释应该怎么写?——注释是解释"为什么",不是解释"是什么"
这是最容易被忽视但最重要的一条原则。
❌ 糟糕的注释(解释"是什么"):
| |
这类注释是在"翻译代码",等于把 count++ 用自然语言重复了一遍。代码本身已经很清楚了,注释只是噪音。
✅ 好的注释(解释"为什么"):
| |
好的注释回答的是:为什么要这样做?有什么特殊原因?有什么坑?
💡 另一个好建议:当你发现需要写很多注释来解释代码时,先问问自己——能不能把代码写得自解释(self-explanatory)?比如,把魔法数字(magic number)提取成命名常量:
1 2 3 4 5 6// 差的写法:魔法数字 if (score > 86400) { ... } // 好的写法:命名常量 final int SECONDS_PER_DAY = 86400; if (score > SECONDS_PER_DAY) { ... }命名良好的变量和方法比长篇注释更有价值。
6.4 Java 代码的缩进与格式化
代码的可读性很大程度上取决于格式是否规范。整齐的代码让人读起来舒服,出错率也更低。
6.4.1 标准的 4 空格缩进
在 Java 社区中,每嵌套一层代码块,缩进 4 个空格是约定俗成的标准。
| |
⚠️ 空格还是 Tab? 很多团队规定使用空格而非 Tab 字符(Tab),因为不同编辑器和终端对 Tab 的显示宽度可能不一致(有的显示为 4 格,有的显示为 8 格)。统一使用 4 个空格可以确保所有环境下代码看起来一致。在 IntelliJ IDEA 中,可以设置
Tab键自动插入 4 个空格。
6.4.2 IDEA 格式化快捷键 Ctrl+Alt+L
如果你使用的是 IntelliJ IDEA(或 Android Studio),最方便的做法是:先随便写,格式的事最后交给 IDE。
选中代码或整个文件,按下 Ctrl + Alt + L(Windows/Linux)或 Cmd + Option + L(Mac),IDE 会自动帮你把代码格式化得整整齐齐——缩进修正、空格规范化、换行合理化。
💡 建议:在提交代码前(无论是 Git commit 还是 Code Review),务必格式化一遍代码。这样团队中每个人看到的代码格式都一致,Review 时不会被格式问题分散注意力。可以在 IDEA 中设置"保存时自动格式化"(Settings → Tools → Actions on Save → Reformat code)。
本章小结
本章我们从经典的 Hello World 程序出发,详细拆解了 Java 代码的各个组成部分:
public class HelloWorld:以public类为基本单元组织代码,类名即文件名。public static void main(String[] args):程序入口方法,static让 JVM 无需实例化即可调用,参数args接收命令行输入。System.out.println("..."):向标准输出打印文字,println会自动换行。- 大小写敏感、类名文件名对应、分号结尾、
{}划分代码块等基本规则,是 Java 编译器强制要求的硬性规定,务必牢记。 - 注释的三种写法(
//、/* */、/** */),注释的价值在于解释"为什么"而非"是什么"。 - 4 空格缩进 + IDE 格式化,保持代码美观整洁是基本职业素养。
学到这里,你已经具备了阅读和编写最简单 Java 程序的能力。下一章,我们将学习 Java 中的变量、数据类型和运算符——程序的核心"原材料"。