为什么 main 方法是 public static void ?
来源:一个老码农的 JVM 笔记刚学 Java 的时候,老师让我们写的第一行代码就是:那时候不懂,只觉得这行代码又长又拗口。为什么要 ?不写行不行?为什么是 ? 又是啥意思?这一串括号和中括号又是闹哪样?今天,我就从“JVM 启动”的角度,把这个问题掰开揉碎,讲个明白。这是最关键的一点。你写的 Java 程序,不是自己跑起来的。它是被 Java 虚拟机(JVM) 启动的。当你在命令行敲下:JVM

刚学 Java 的时候,老师让我们写的第一行代码就是:
public static void main(String[] args) {
System.out.println("Hello, World!");
}
那时候不懂,只觉得这行代码又长又拗口。
为什么要 public?不写行不行?
为什么是 static?void 又是啥意思?String[] args 这一串括号和中括号又是闹哪样?
今天,我就从“JVM 启动”的角度,把这个问题掰开揉碎,讲个明白。
一、main 方法是谁调用的?——答案是:JVM
这是最关键的一点。
你写的 Java 程序,不是自己跑起来的。
它是被 Java 虚拟机(JVM) 启动的。
当你在命令行敲下:
java HelloWorld
JVM 做了这么几件事:
- 加载
HelloWorld.class文件 - 在这个类里找一个叫
main的方法 - 直接调用它,开始执行你的代码
注意:此时,你的类还没有任何实例(对象)。
JVM 还没 new 过你这个类。
所以问题来了:
“一个还没被 new 的类,怎么调用它的方法?”
答案只能是:这个方法必须是 static 的。
二、为什么必须是 static?
我们来对比一下:
// ❌ 普通方法:属于对象
public void main() {
// 必须先 new 才能调
}
// ✅ 静态方法:属于类
public static void main() {
// 不需要 new,直接调
}
JVM 启动时,不可能先去 new HelloWorld(),因为它根本不知道该怎么构造你这个类——说不定你的构造函数还要传参数呢!
所以,唯一可行的方式就是调用一个不需要实例的 static 方法。
这就是 static 的由来:让 JVM 能在不创建对象的情况下直接调用。
三、为什么必须是 public?
因为 JVM 要调用它。
public 是 Java 的访问控制符,意思是“对外公开”。
如果 main 是 private 或 protected,那它只能被自己类或子类访问。
但 JVM 是“外部调用者”,它不属于你的类,也不属于任何包内类。
只有 public 方法,它才能跨包、跨类、跨世界地调用。
你可以试试把 main 改成 private:
private static void main(String[] args) {
System.out.println("试试看");
}
运行时会报错:
Main method not found in class XXX, please define the main method as: public static void main(String[] args)
JVM 直接拒绝执行。
四、为什么返回类型是 void?
因为 JVM 不关心你返回什么。
main 方法是程序的入口,就像一栋大楼的正门。
JVM 从这个门进来,执行你的逻辑,执行完了就退出。
它不需要你“交个结果”给它。
你要想传递信息,可以通过:
System.exit(0)返回状态码- 打印日志
- 写文件
- 调用其他服务
但方法本身的返回值,JVM 并不接收。
所以,它被设计为 void —— 无返回值。
你当然可以想象一个设计:int main(),然后 JVM 根据返回值判断成功失败。
但 Java 没这么干,而是用 System.exit(int) 来统一处理退出状态。
五、String[] args 是干嘛的?
这是给程序传参数用的。
比如你写了个工具类:
public class FileProcessor {
public static void main(String[] args) {
if (args.length > 0) {
System.out.println("处理文件:" + args[0]);
}
}
}
你可以这样运行:
java FileProcessor config.txt
这时,args[0] 就是 "config.txt"。
args 是 “arguments” 的缩写,String[] 表示字符串数组。
所有命令行参数都会以字符串形式传进来。
六、能不能没有 main 方法?
能,但不是“没有入口”,而是“入口变了”。
- Java 8 及以下:必须有
main - Java 17+ 的 “Hello World” 简化模式:你可以写一个
.java文件直接运行,编译器会自动帮你生成main - Spring Boot 项目:你可能找不到
main?不,它在@SpringBootApplication标注的类里,只是被 IDE 折叠了 - Applet、Servlet、Android(早期):它们的入口不是
main,而是由容器(如浏览器、Tomcat)调用特定生命周期方法
但归根结底,JVM 启动一个独立程序,还是得靠 main。
七、总结:public static void main 的每一部分都不能少
| 关键字 | 为什么必须存在 |
|---|---|
public |
JVM 要能外部访问,不能被访问控制挡住 |
static |
不需要创建对象就能调用,否则 JVM 无法启动 |
void |
JVM 不接收返回值,退出状态通过 System.exit() 控制 |
main |
约定俗成的入口名,JVM 硬编码查找 |
String[] args |
支持命令行参数传递,灵活 |
更多推荐


所有评论(0)