1.2 逐行理解 Java 代码
前置知识:已经运行过 Hello World
预计时间:20 分钟
说明:解释 Java 17 项目常见的传统入口写法
完成标志:能用自己的话解释类、入口方法、输出语句和作用域
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}public class HelloWorld
这一行声明一个顶层类。
| 片段 | 当前要理解的意思 |
|---|---|
class | 声明一个类;类可以组织数据和方法 |
HelloWorld | 类名,由程序作者选择,Java 区分大小写 |
public | 这个顶层类可以被其他包中的代码访问 |
公开顶层类还有一条文件规则:它必须位于同名源文件中。因此 public class HelloWorld 应放在 HelloWorld.java 里。
这并不意味着一个源文件只能声明一个类。一个编译单元可以包含多个顶层类型,但至多有一个 public 顶层类型,而且公开类型要与文件名对应。初学阶段保持“一文件一个主要类”最清楚。
public static void main(String[] args)
在本卷采用的 Java 17 传统写法中,java -cp out HelloWorld 会寻找这个入口方法并调用它。
| 片段 | 作用 | 后续章节 |
|---|---|---|
public | 让启动器可以访问这个方法 | 第 7 章 |
static | 方法属于类;调用入口前不必先创建 HelloWorld 对象 | 第 7 章 |
void | 方法正常结束时不返回一个 Java 值 | 第 5 章 |
main | 启动器约定的入口名称 | 本讲记住 |
String[] args | 接收命令行参数的字符串数组 | 第 6 章 |
static 不是“程序启动时已经造好一个方法”。更准确的说法是:它是类方法,可以通过类来调用,不依赖某个实例。
参数变量不一定要叫 args,下面也能作为入口:
public static void main(String[] words) {
System.out.println(words.length);
}数组括号也可以写在变量名后,String words[] 在语法上有效,但 Java 代码通常采用 String[] words,因为类型更容易读。可变参数写法 String... words 也会编译成可接受的入口签名。初学时统一使用 String[] args。
如果还保留着同样的 HelloWorld.java,可重新编译后传入两个参数:
java -cp out HelloWorld north east此时数组中的两个元素是 north 和 east。若保留页首问候程序,输出仍是问候语;若换成上面的 words.length 版本,输出是 2。
System.out.println("Hello World!");
从左到右看:
System是java.lang包中的标准库类;java.lang会被编译器自动导入。out是System暴露的标准输出流,类型是PrintStream。println(...)调用输出流的方法,写出参数后结束当前行。"Hello World!"是字符串字面量;双引号本身不属于输出内容。;结束这条方法调用语句。
对比 print:
System.out.print("A");
System.out.print("B");
System.out.println("C");输出为:
ABCprintln 使用当前平台的行分隔方式。它不是简单地在所有系统上都追加同一个字符。
花括号表示结构边界
public class HelloWorld { // 类体开始
public static void main(String[] args) { // 方法体开始
System.out.println("Hello World!");
} // 方法体结束
} // 类体结束先打开的外层结构最后关闭:
HelloWorld 类
└── main 方法
└── println 调用编译器主要依靠记号和花括号理解结构,缩进不会改变 Java 语义。但缩进能让人看出嵌套关系,也能更早发现少写了哪一个 }。本仓库统一使用四个空格缩进。
// 是单行注释
// 这一行给读者看,编译器不会把它当作执行语句
System.out.println("Hello World!"); // 行尾也可以写注释注释应解释“为什么”,而不是逐字复述代码。文件名提示可以写在代码块外,避免初学者误以为注释是程序必需部分。
Python 与 C++ 对照
Python 常用缩进划分代码块:
def main():
print("Hello World!")
if __name__ == "__main__":
main()Java 用花括号确定结构,Python 把缩进纳入语法。Python 示例中的守卫是常见约定,不是每个 Python 文件都必须拥有的入口声明。
C++ 的入口返回 int:
#include <iostream>
int main() {
std::cout << "Hello World!\n";
}从 main 末尾正常走出等价于返回 0。Java 的传统 main 返回 void;若要向操作系统报告非零退出状态,可以显式调用 System.exit(code),但本讲不需要这样做。
专业速查
| 需要确认 | 最短答案 |
|---|---|
| 源文件名 | 公开顶层类名 + .java |
| 传统入口 | public static void main(String[] args) |
| 标准输出 | System.out |
| 打印并结束当前行 | println |
| 类体、方法体边界 | 成对花括号 |
| 命令行参数 | args 中的字符串元素 |
离开这一页前
不看代码,试着解释 static 为什么让入口不需要对象、args 为什么不是关键字、print 与 println 有什么差别,以及公开顶层类为何要与文件名对应。说不清的词再回到对应小节,不必整段背入口签名。
结构已经看清,下一讲把容易混淆的语法规则说准确。