1. 概述

在运行 Java 程序时,你可能遇到过这个经典错误:

Error: Could not find or load main class

从字面就能猜到:JVM 找不到主类。但为什么找不到?是拼写错了?路径不对?还是包名搞混了?

本文将带你深入分析这个错误的常见成因,并给出简单粗暴的解决方案。✅ 老手踩坑回顾,新手避坑指南。


2. 示例程序

我们从一个最简单的 HelloWorld 开始:

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello world..!!!");
    }
}

先编译:

$ javac HelloWorld.java

✅ 编译成功后会生成 HelloWorld.class 文件,且与源文件同目录。

⚠️ 关键点:.class 文件名严格匹配类名(包括大小写),这是后续很多问题的根源。

接下来我们尝试运行这个 class 文件,看看哪些操作会触发“找不到主类”的错误。


3. 类名错误

运行 Java 程序的命令是:

java <类名>

注意:这里传的是类名,不是文件名。

❌ 错误示例:大小写不匹配

$ java helloworld
Error: Could not find or load main class helloworld

虽然文件系统(尤其是 Windows/macOS)对大小写不敏感,但 JVM 是严格区分大小写的。

我们的类叫 HelloWorld,不是 helloworld

✅ 正确做法:使用正确类名

$ java HelloWorld
Hello world..!!!

搞定。输出如预期。


3.1 不要加 .class 后缀

另一个常见误区是加上 .class 扩展名:

$ java HelloWorld.class
Error: Could not find or load main class HelloWorld.class

❌ 错了!JVM 会把 HelloWorld.class 当作一个名为 “HelloWorld.class” 的类去查找,显然不存在。

✅ 正确姿势:

$ java HelloWorld

记住口诀:**编译带 .java,运行不带 .class**。


4. 包名(Package)导致的问题

Java 中常用 package 组织代码。我们把 HelloWorld 放进 com.baeldung 包:

package com.baeldung;

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello world..!!!");
    }
}

目录结构变为:

com/
  baeldung/
    HelloWorld.java

编译:

$ javac com/baeldung/HelloWorld.java

生成的 .class 文件在 com/baeldung/HelloWorld.class

❌ 错误尝试:直接用类名运行

$ java HelloWorld
Error: Could not find or load main class HelloWorld

❌ 又错了!因为一旦类在 package 中,就不能再用简单类名运行。

✅ 正确做法:使用全限定类名(Fully Qualified Class Name)

$ java com.baeldung.HelloWorld
Hello world..!!!

但注意!这个命令必须在项目根目录下执行(即 com 目录的父目录),否则仍然会失败。

❌ 踩坑示例:在包目录下运行

假设你现在位于 com/baeldung/ 目录:

$ pwd
/path/to/project/com/baeldung

$ java com.baeldung.HelloWorld
Error: Could not find or load main class com.baeldung.HelloWorld

JVM 会尝试在 ./com/baeldung/com/baeldung/HelloWorld.class 找类,显然不存在。

✅ 解决方案:回到根目录再运行:

$ cd ../../
$ java com.baeldung.HelloWorld
Hello world..!!!

5. Classpath 设置错误

什么是 Classpath?

Classpath 是 JVM 用来查找 .class 文件的路径集合。你可以把它理解为“类的搜索目录”。

  • 默认值是当前目录(.
  • 可通过 -classpath-cp 参数指定

场景:想从任意目录运行程序

比如你现在在 com/baeldung/ 目录,又不想切换回去,怎么办?

使用 -classpath 显式指定根路径:

$ java -classpath ../../ com.baeldung.HelloWorld
Hello world..!!!

解释:

  • ../../ 是 classpath,指向包的根目录
  • com.baeldung.HelloWorld 是全限定类名

等价写法(更清晰):

$ java -cp ../.. com.baeldung.HelloWorld
Hello world..!!!

✅ 小结:classpath 使用要点

  • 当类在 package 中时,classpath 必须指向包的根目录
  • 全限定类名不能包含 .class 后缀
  • 路径分隔符:
    • Linux/macOS: :
    • Windows: ;

示例(多个路径):

$ java -cp /lib/mylib.jar:./classes com.baeldung.HelloWorld

6. 总结

问题原因 解决方案
❌ 类名大小写错误 ✅ 使用正确的类名(区分大小写)
❌ 加了 .class 后缀 ✅ 运行时只传类名
❌ 忽略 package 导致类名不全 ✅ 使用全限定类名(如 com.baeldung.HelloWorld
❌ 在错误目录运行 ✅ 在包根目录下运行,或用 -cp 指定
❌ classpath 设置错误 ✅ 确保 -cp 指向包含包根的目录

⚠️ 最后提醒:这个错误看似低级,但在 Maven/Gradle 项目结构不熟、手动编译运行时依然高频出现。理解 classpath 和包机制,是 Java 开发的基本功。

遇到 “Could not find or load main class”?别慌,按上面几点逐条排查,99% 都能快速解决。


原始标题:Java – “Could Not Find or Load Main Class” Error | Baeldung