Java虚拟机唯一识别public static void main(String[] args)这一签名,参数名和数组声明形式可变但类型与维度不可改,非public类或文件名不匹配会导致类加载失败,var和模块未导出亦引发运行错误。

main方法必须是public static void类型的
Java虚拟机只认一种签名的入口方法,任何偏差都会导致“找不到主类”或“Main method not found”错误。不是public、漏了static、返回类型写成int或String,统统不认。
常见错误现象:
- 运行时报错:
Error: Main method not found in class X, please define the main method as: public static void main(String[] args) - IDE能编译通过但无法运行(比如把
static误写成final)
正确签名只有一种:public static void main(String[] args)。其他变体如public static void main(String... args)虽语法合法,但JVM不识别——可编译,不可作为入口。
参数名和数组声明形式可以变化,但类型和维度不能改
args只是习惯命名,换成argv或arguments都行;String[] args和String args[]在Java中等价,都是合法的。
立即学习“Java免费学习笔记(深入)”;
但以下写法全部无效:
-
String args(缺数组符号) -
String[][] args(二维数组) -
Object[] args(类型不匹配) -
public static void main(String... args)(可变参数,JVM不识别)
示例对比:
public static void main(String[] args) // ✅ 正确 public static void main(String args[]) // ✅ 合法,等价 public static void main(String... args) // ❌ 编译过,但运行报错
main方法必须定义在public类中,且类名与文件名严格一致
如果类声明为public class Hello,那么文件名必须是Hello.java。否则即使main写对了,javac编译会失败,或java命令执行时抛出NoClassDefFoundError。
容易被忽略的细节:
- 大小写敏感:Linux/macOS下
hello.java和Hello.java是不同文件 - 非public类可以有main方法,但不能用
java 类名直接运行(需通过其他public类调用) - 一个文件里可以有多个类,但只能有一个public类,且必须与文件同名
main方法里不能用var声明参数,也不能依赖模块系统隐式导包
JDK 10+支持var局部变量推导,但main签名是JVM硬编码识别的,不接受var args这类写法——它根本不是变量声明,而是方法签名的一部分。
另外,如果用了模块系统(module-info.java),记得显式导出含main的包,否则即使类存在,启动时也可能因模块不可见而失败。
典型陷阱:
-
public static void main(var args[])→ 编译错误:非法的类型 - 模块未导出,运行时报
java.lang.NoClassDefFoundError或静默失败
复杂点在于:错误可能不直接指向main本身,而是藏在类加载或模块可见性层面,调试时得往java -p、--add-exports这些地方查。









