从 TypeScript 到 Java(2):从脚本执行到 main 方法 ------ 理解 Java 的程序入口
系列导读: 本系列面向有 TypeScript 基础的开发者,帮助你快速掌握 Java 的核心语法与运行机制。 本篇,我们将聚焦于 Java 程序的"起点"------
main方法。在 TypeScript 中,文件可以直接执行; 而在 Java 中,程序的启动必须经过一个固定的入口函数。 理解这一点,能让你真正看懂 Java 程序的执行流程。
Java 程序总是从 main 开始,而 TypeScript 则可以从任何文件的顶部开始。

💡 TypeScript 与 Java:两种完全不同的启动哲学
在 TypeScript 或 Node.js 环境下,我们常常这样写:
typescript
console.log("Hello TypeScript!");
保存为 app.ts,然后执行:
bash
npx ts-node app.ts
它就能立即运行。 TypeScript 没有强制的"入口函数",任何文件都可以是入口。
而 Java 则不同。 在 Java 世界中,程序的执行必须从一个类的 main 方法开始。 JVM(Java Virtual Machine)在运行程序时,会主动寻找这个入口。
🚪 Java 程序的入口:main 方法
一个最简单的 Java 程序如下:
java
public class App {
public static void main(String[] args) {
System.out.println("Hello Java!");
}
}
运行命令:
bash
javac App.java # 编译为 App.class
java App # 运行
输出:
Hello Java!
看似简单的 main 方法,其实蕴含了 Java 运行机制的核心逻辑。
🧩 解析 main 方法的完整声明
java
public static void main(String[] args)
逐个拆解含义:
| 关键字 | 含义 |
|---|---|
public |
必须是公开的,JVM 才能从外部调用 |
static |
属于类本身,而不是对象;JVM 无需实例化即可执行 |
void |
无返回值 |
main |
固定方法名,JVM 通过此名称识别入口 |
String[] args |
命令行参数,以字符串数组形式传入 |
理解重点:
- 你不能随意修改
main方法的签名; - 可以存在多个类,但只有一个类拥有有效的入口;
- 一个项目中可以有多个
main方法,用于测试不同模块。
📦 main 方法与类的关系
在 TypeScript 中,我们可以在文件顶部写任意逻辑,比如:
typescript
const user = { name: "Alice" };
console.log("Hello", user.name);
Java 则不允许"裸代码"存在于类外。 你必须把逻辑放入方法或静态代码块中:
java
public class Hello {
static {
System.out.println("静态代码块执行");
}
public static void main(String[] args) {
System.out.println("主方法执行");
}
}
运行时输出:
静态代码块执行
主方法执行
迁移思维: TypeScript 运行逻辑是从文件顶部顺序执行; Java 程序执行顺序则严格由类加载 → 静态代码块 → main 方法决定。
⚙️ 命令行参数传递
Java 的 main(String[] args) 支持外部参数,类似于 Node.js 的 process.argv。
示例:
java
public class ArgsDemo {
public static void main(String[] args) {
for (String arg : args) {
System.out.println("参数:" + arg);
}
}
}
运行:
bash
java ArgsDemo hello world 123
输出:
参数:hello
参数:world
参数:123
对比 TypeScript:
typescript
process.argv.forEach(arg => console.log(arg));
两者功能一致,但 Java 的参数解析完全由 JVM 传递。
🧠 main 方法背后的 JVM 调用逻辑
当你执行 java App 时,JVM 做了以下几件事:
- 加载
App类; - 执行静态初始化代码;
- 查找
public static void main(String[] args); - 创建一个
String[]数组存放命令行参数; - 调用
App.main(args); - 当 main 方法执行完毕,JVM 退出。
整个过程完全由 JVM 控制,因此方法签名必须严格符合规范。
🧪 实战:编写一个多入口小程序
项目结构:
css
src/
└── main/
└── java/
└── com/example/app/
├── MainA.java
└── MainB.java
MainA.java:
java
package com.example.app;
public class MainA {
public static void main(String[] args) {
System.out.println("入口 A 启动!");
}
}
MainB.java:
java
package com.example.app;
public class MainB {
public static void main(String[] args) {
System.out.println("入口 B 启动!");
}
}
运行:
bash
java com.example.app.MainA
java com.example.app.MainB
输出:
css
入口 A 启动!
入口 B 启动!
在一个项目中,你可以定义多个 main 方法,但每次运行时只会执行一个入口。
🧭 TypeScript vs Java 执行模型对比
| 对比项 | TypeScript | Java |
|---|---|---|
| 程序入口 | 任意文件 | public static void main(String[] args) |
| 执行方式 | 解释执行 / 转译运行 | 编译后由 JVM 启动 |
| 命令行参数 | process.argv |
String[] args |
| 代码位置 | 可写在文件顶层 | 必须写在类中 |
| 运行控制 | 自由 | 严格由 JVM 控制 |
小结: Java 的执行模型更像"正式工程",有严格的入口和生命周期管理; TypeScript 则更灵活,适合脚本型和工具型开发。
⚡ 小技巧:快速创建与运行 Java 程序
无需创建完整项目,也可以用单文件运行(Java 11+):
bash
java Hello.java
示例文件:
java
public class Hello {
public static void main(String[] args) {
System.out.println("Hello from Java 11+");
}
}
这在学习阶段非常方便,类似 npx ts-node 的体验。
✅ 小结
main 方法是 Java 程序的灵魂。 理解它,你就理解了 Java 程序的启动方式与运行机制。
核心记忆点:
- Java 程序总是从
public static void main(String[] args)开始; - 所有代码必须放在类中;
- main 方法的签名和修饰符必须完全正确;
- JVM 严格控制程序生命周期。
当你掌握 main 方法的结构和启动流程后, 你就能开始写出第一个完整的 Java 控制台程序 🚀。
👉 下一篇预告
《Java 的类型系统:从动态到强类型的思维转变》 我们将深入理解 Java 的基本类型、引用类型、类型推断和内存模型。