"Could not find or load main class"是什么意思?

回答 64 浏览 435.9万 2013-08-07

新 Java 开发人员遇到的一个常见问题是他们的程序无法运行并显示错误消息:Could not find or load main class ...

这是什么意思,是什么原因造成的,以及应该如何解决?

Stephen C 提问于2013-08-07
请注意,这是一个“自我回答”问题,旨在为新 Java 用户提供通用参考问答。我找不到充分涵盖这一点的现有问答(IMO)。Stephen C 2013-08-07
64 个回答
#1楼 已采纳
得票数 1622

java <class-name> 命令语法

首先,您需要了解使用java(或javaw)命令启动程序的正确方法。

正常语法1是这样的:

    java [ <options> ] <class-name> [<arg> ...]

其中 <option> 是命令行选项(以“-”字符开头),<class-name> 是完全限定的 Java 类名,<arg> 是传递到应用程序的任意命令行参数。


1 - 在本答案末尾附近描述了一些其他语法。

类的完全限定名 (FQN) 按照惯例按照 Java 源代码中的方式编写;例如

    packagename.packagename2.packagename3.ClassName

然而,java 命令的某些版本允许您使用斜杠而不是句点;例如

    packagename/packagename2/packagename3/ClassName

它(令人困惑地)看起来像一个文件路径名,但实际上不是。请注意,术语完全限定名称是标准Java术语......不是我为了让您感到困惑而编造的东西:-)

以下是 java 命令的示例:

    java -Xmx100m com.acme.example.ListUsers fred joe bert

上述内容将导致java命令执行以下操作:

  1. 搜索com.acme.example.ListUsers类的编译版本。
  2. 加载类。
  3. 检查该类是否有一个main方法,其签名返回类型修饰符public static void main(String[])所示。 (请注意,方法参数的名称不是签名的一部分。)
  4. 调用该方法,将命令行参数(“fred”、“joe”、“bert”)作为 String[] 传递给它。

Java找不到类的原因

当您收到消息"Could not find or load main class ..."时,这意味着第一步失败了。 java 命令无法找到该类。事实上,消息中的“...”将是java 正在寻找的完全限定类名

那么为什么会找不到班级呢?

原因#1 - 你在类名参数上犯了一个错误

第一个可能的原因是您可能提供了错误的类名。 (或者......正确的类名,但形式错误。)考虑上面的示例,这里有各种指定类名的错误方法

  • 示例#1 - 一个简单的类名:

    java ListUser
    

    当类在包(例如com.acme.example)中声明时,您必须在java命令中使用完整的类名包括包名称;例如

    java com.acme.example.ListUser
    
  • 示例 #2 - 文件名或路径名而不是类名:

    java ListUser.class
    java com/acme/example/ListUser.class
    
  • 示例 #3 - 大小写不正确的类名:

    java com.acme.example.listuser
    
  • 示例 #4 - 拼写错误

    java com.acme.example.mistuser
    
  • 示例 #5 - 源文件名(Java 11 或更高版本除外;见下文)

    java ListUser.java
    
  • 示例#6 - 你完全忘记了类名

    java lots of arguments
    

原因 #2 - 应用程序的classpath指定不正确

第二个可能的原因是类名是正确的,但java命令找不到该类。要理解这一点,您需要理解“classpath”的概念。 Oracle 文档对此进行了很好的解释:

所以...如果您正确指定了类名,接下来要检查的是您是否正确指定了classpath:

  1. 阅读上面链接的三个文档。 (是的......阅读它们!Java 程序员至少要理解 Java 类路径机制如何工作的基础知识,这一点很重要。)
  2. 查看运行 java 命令时有效的命令行和/或 CLASSPATH 环境变量。检查目录名和 JAR 文件名是否正确。
  3. 如果classpath中有相对路径名,请检查它们是否从运行 java 命令时有效的当前目录正确解析。
  4. 检查该类(错误消息中提到的)是否可以位于有效classpath上。
  5. 请注意,Windows 与 Linux 和 Mac OS 的classpath语法不同。 (classpath分隔符在 Windows 上为 ;,在其他平台上为 :。如果您在您的平台上使用了错误的分隔符,您将不会收到明确的错误消息。相反,路径上会出现一个不存在的文件或目录,并被默默忽略。)

原因 #2a - classpath上的目录错误

当您将目录放在classpath上时,它理论上对应于限定名称空间的根。类位于根目录下的目录结构中,通过将完全限定名称映射到路径名。例如,如果“/usr/local/acme/classes”位于classpath上,那么当 JVM 查找名为 com.acme.example.Foon 的类时,它将查找具有以下路径名的“.class”文件:

  /usr/local/acme/classes/com/acme/example/Foon.class

如果您将“/usr/local/acme/classes/com/acme/example”放在classpath中,那么 JVM 将无法找到该类。

原因 #2b - 子目录路径与 FQN 不匹配

如果您的类 FQN 是 com.acme.example.Foon,那么 JVM 将在目录“com/acme/example”中查找“Foon.class”:

  • 如果您的目录结构与上述模式中的包命名不匹配,JVM 将找不到您的类。

  • 如果您尝试通过移动类来重命名它,那也会失败……但是异常堆栈跟踪将会有所不同。它可能会这样说:

    Caused by: java.lang.NoClassDefFoundError: <path> (wrong name: <name>)
    

    因为类文件中的 FQN 与类加载器期望找到的不匹配。

举一个具体的例子,假设:

  • 你想运行com.acme.example.Foon类,
  • 完整文件路径是/usr/local/acme/classes/com/acme/example/Foon.class
  • 您当前的工作目录是/usr/local/acme/classes/com/acme/example/

然后:

# wrong, FQN is needed
java Foon

# wrong, there is no `com/acme/example` folder in the current working directory
java com.acme.example.Foon

# wrong, similar to above
java -classpath . com.acme.example.Foon

# fine; relative classpath set
java -classpath ../../.. com.acme.example.Foon

# fine; absolute classpath set
java -classpath /usr/local/acme/classes com.acme.example.Foon

笔记:

  • 在大多数 Java 版本中,-classpath 选项可以缩写为 -cp。检查 javajavac 等相应的手册条目。
  • 在classpath中的绝对路径名和相对路径名之间进行选择时请仔细考虑。请记住,如果当前目录发生更改,相对路径名可能会“中断”。

原因 #2c - classpath中缺少依赖项

classpath需要包含应用程序依赖的所有其他(非系统)类。 (系统类是自动定位的,您很少需要关心这一点。)为了正确加载主类,JVM 需要找到:

(注意:JLS 和 JVM 规范允许 JVM 在一定范围内“延迟”加载类,这可能会影响抛出类加载器异常的时间。)

原因 #3 - 该类已在错误的包中声明

偶尔会发生这样的情况:有人将源代码文件放错了源代码树中的文件夹,或者漏掉了 package 声明。如果您在 IDE 中执行此操作,IDE 的编译器会立即告诉您这一点。同样,如果您使用合适的 Java 构建工具,该工具将以检测问题的方式运行 javac。但是,如果您手动构建 Java 代码,则可以采用编译器不会注意到问题的方式,并且生成的“.class”文件不会位于您期望的位置。

还是找不到问题?

需要检查的东西很多,而且很容易漏掉一些东西。尝试将-Xdiag选项添加到java命令行(作为java之后的第一件事)。它会输出有关类加载的各种信息,这可能会为您提供有关真正问题是什么的线索。

另外,请考虑从网站、文档等复制和粘贴不可见或非 ASCII 字符可能导致的问题。并考虑“同形文字”,其中两个字母或符号看起来相同......但事实并非如此。

如果META-INF/*.SF 中的签名无效或不正确,您可能会遇到此问题。您可以尝试在您最喜欢的 ZIP 编辑器中打开 .jar,然后从 META-INF 中删除文件,直到只剩下 MANIFEST.MF。然而,一般情况下不建议这样做。 (无效签名可能是由于有人将恶意软件注入到原始签名的 JAR 文件中而导致的。如果删除无效签名,您的应用程序就会被恶意软件感染!)建议的方法是获取具有有效签名的 JAR 文件。签名,或从(真实的)原始源代码重建它们。

最后,如果 MANIFEST.MF 文件中存在语法错误,您显然会遇到此问题(请参阅 https://stackoverflow.com /a/67145190/139985)。


java 的替代语法

使用java command启动Java程序有三种替代语法。

  1. 用于启动“可执行”JAR 文件的语法如下:

    java [ <options> ] -jar <jar-file-name> [<arg> ...]
    

    例如

    java -Xmx100m -jar /usr/local/acme-example/listuser.jar fred
    

    入口点类的名称(即com.acme.example.ListUser)和classpath在 JAR 文件的 MANIFEST 中指定。使用以下语法,您在命令行上指定为classpath的任何内容都将被忽略:仅使用清单中的 Class-Path 条目(以及该条目引用的任何 JAR 文件中的条目)。另请注意,此 Class-Path 中的 URL相对于它所包含的 JAR 的位置。

  2. 从模块(Java 9 及更高版本)启动应用程序的语法如下:

    java [ <options> ] --module <module>[/<mainclass>] [<arg> ...]
    

    入口点类的名称要么由<module>本身定义,要么由可选的<mainclass>给出。

  3. 从 Java 11 开始,您可以使用 java 命令使用以下语法来编译和运行单个源代码文件:

    java [ <options> ] <sourcefile> [<arg> ...]
    

    其中<sourcefile>(通常)是后缀为“.java”的文件。

有关更多详细信息,请参阅您所使用的 Java 版本的 java 命令的官方文档。


IDE

典型的 Java IDE 支持在 IDE JVM 本身或子 JVM 中运行 Java 应用程序。这些通常不受此特定异常的影响,因为 IDE 使用自己的机制来构造运行时classpath、识别主类并创建 java 命令行。

但是,如果您在 IDE 后面执行操作,则仍然有可能发生此异常。例如,如果您之前在 Eclipse 中为 Java 应用程序设置了应用程序启动器,然后将包含“主”类的 JAR 文件移动到文件系统中的其他位置,没有告诉 Eclipse ,Eclipse 会无意中使用不正确的类路径启动 JVM。

简而言之,如果您在 IDE 中遇到此问题,请检查 IDE 状态是否陈旧、项目引用损坏或启动器配置损坏等。

IDE 也可能会感到困惑。 IDE 是非常复杂的软件,由许多交互部分组成。其中许多部分采用了各种缓存策略,以使 IDE 作为一个整体具有响应能力。这些有时可能会出错,一种可能的症状是启动应用程序时出现问题。如果您怀疑可能会发生这种情况,则值得尝试其他方法,例如重新启动 IDE、重建项目等。


其他参考资料

Stephen C 提问于2013-08-07
user207421 修改于2023-10-20
当我尝试使用第三方库运行类时,我遇到了这个问题。我这样调用java:java -cp ../third-party-library.jar com.my.package.MyClass;这不起作用,而是需要将本地文件夹也添加到类路径中(用:分隔,如下所示:java -cp ../third-party-library.jar:. com.my.package.MyClass,然后它应该可以工作lanoxx 2014-02-08
经过多年的 java 编程,我仍然成功地到达了这个页面。对我来说,问题是类路径语法取决于操作系统。我对 Windows 编程有点陌生,不知道。keyser 2015-01-31
补充说明,第2点救救我!令人遗憾的是,java 并没有说它没有找到导入的类,而是说您正在尝试运行的主类。这是一种误导,尽管我确信这是有原因的。我遇到过这样的情况:java 确切地知道我的类在哪里,但它找不到导入的类之一。它没有这么说,而是抱怨找不到我的主类。确实,烦人。MSX 2016-10-03
我在 Eclipse 中遇到过两次这个问题。第一次 main() 的签名是错误的。第二次我重命名了 .jar,即使我将新的 .jar 添加到构建路径中,Eclipse 也没有找到旧的,因此该项目无法编译,并出现此错误。我必须从“项目”>“属性”>“Java 构建路径”>“库”中删除 .jar 文件。GregT 2018-01-18
我已经第三次遇到了。我已经从 Windows 10 批处理文件运行该程序,并将 .jar 名称放入变量中(用“-cp %jarname%;lib*”调用)。我错误地在 jarname 末尾添加了一个额外的空格,这导致了错误。GregT 2018-05-09
#2楼
得票数 301

如果您的源代码名称是HelloWorld.java,则编译后的代码将为HelloWorld.class

如果您使用以下方式调用它,您将收到该错误:

java HelloWorld.class

相反,使用这个:

java HelloWorld
panoet 提问于2014-05-21
Paolo Forgia 修改于2017-09-04
问题在于,此解决方案仅适用于在默认包中声明且没有 JAR 文件依赖项的 Java 类。 (即使如此,也并非总是如此。)大多数 Java 程序都没有那么简单。Stephen C 2015-09-29
就像 Stephen 所说,这只适用于“默认包”——这意味着文件顶部没有包声明。为了快速测试一些代码,我做了:javac TestCode.java,然后是java TestCodeSomeone Somewhere 2016-01-03
这对我不起作用。它仍然显示"Could not find or load main class HelloWorld"Jim 2016-08-05
我需要做java -classpath . HelloWorldChris Prince 2017-01-31
@ChrisPrince - 是的......有时有效。要了解它何时有效以及何时无效,请阅读投票最高的答案。Stephen C 2017-09-08
#3楼
得票数 177

如果您的类位于包中,那么您必须 cd 到项目的根目录并使用该类的完全限定名称 (packageName.MainClassName) 运行。

例子:

我的class在这里:

D:\project\com\cse\

我的主类的完全限定名称是:

com.cse.Main

所以我cd回到项目根目录:

D:\project

然后发出java命令:

java com.cse.Main

这个答案是为了让 Java 新手程序员免受常见错误带来的挫败感。我建议您阅读已接受的答案,以更深入地了解 Java 类路径。

tharinduwijewardane 提问于2015-03-06
Peter Mortensen 修改于2022-02-02
这个答案做出了很多假设。还有其他方法可以实现这一目标。我建议人们花时间阅读我的答案中解释 Java 类路径如何工作的链接,而不是盲目遵循上述建议。最好理解你在做什么......Stephen C 2015-03-06
这个答案做出了我需要的确切假设:)我位于 .class 文件的目录中,并且 java.exe 无法工作。一旦我在上面进行了 cd 编辑并使用命令行中包含的包名称运行,它就起作用了。Nick Constantine 2019-04-14
我同意Nick Constantine的观点。同样在这里。这是一个遵循我所做步骤的精确示例,它也对我有用。 java 类路径处理有一定的逻辑,但我肯定不会那样设计。Tihamer 2020-08-20
Tnanks,你的回答帮助我看看我使用了 Main 和大写 _Hernaldo Gonzalez 2021-09-20
我在尝试此操作后写了此评论,但没有成功。我有一个名为 Helloworld 的项目,仅包含 1 个 java 文件,Helloworld/src/com/firstpackage/Test.java (windows 10.intellij idea)。 我没有 CLASSPATH 环境变量,我想专门为此项目设置类路径。在 Helloworld 目录中运行 java com.firstpackage.Test 不起作用,命令 java -classpath C:\Users\matuagkeetarp\IdeaProjects\Helloworld\src\com\first‌​package Test.java set classpath 变量也不起作用。你能帮我吗?Prateek Gautam 2021-11-15
#4楼
得票数 116

使用关键字“package”

如果源代码中有package关键字(主类在包中定义),则应使用类的全名(packageName.MainClassName )。

假设有一个源代码文件(Main.java):

package com.test;

public class Main {

    public static void main(String[] args) {
        System.out.println("salam 2nya\n");
    }
}

要运行此代码,您应该将 Main.Class 放在类似包的目录中:

C:\Users\workspace\testapp\com\test\Main.Java

然后将终端的当前目录更改为项目的根目录:

cd C:\Users\workspace\testapp

最后,运行代码:

java com.test.Main

没有关键字“package”

如果您的源代码名称中没有任何包,则可能您使用了错误的命令。假设你的Java文件名为Main.java,编译后:

javac Main.java

你编译后的代码将是Main.class

如果您使用以下方式调用它,您将收到该错误:

java Main.class

相反,使用这个:

java Main
M-Razavi 提问于2014-10-27
M-Razavi 修改于2022-02-03
请参阅我的答案的“附加注释#1”。为了更好地解释这个问题。Stephen C 2014-10-27
@StephenC是的,你的答案更完整(当然,+1),但是这个特定的答案中有“包”这个词,这让我可以快速找到我需要的东西。它起作用了。所以+1 Razavi。 StephenC,你的缺少我需要的简单包示例,因为我是 Java 新手。kmort 2014-10-29
这正是我的问题。我已经阅读了大量的 Java 文档,这个具体的例子正是我所需要的John 2015-03-17
是的,具体的例子很好,这非常有效。我确信主要答案是非常彻底的,但很难只见树木。不错的@Razaviuser1300214 2018-05-09
我喜欢这个简短而有用的答案,而不是接受的答案!Mohsen 2019-04-18
#5楼
得票数 63

当相同的代码在一台 PC 上运行,但在另一台 PC 上显示错误时,我发现的最佳解决方案是按如下方式进行编译:

javac HelloWorld.java
java -cp . HelloWorld
Enamul Hassan 提问于2015-08-21
Peter Mortensen 修改于2017-01-14
这不是一个好的建议。您依赖于未设置的 CLASSPATH 环境变量,或者具有与“.”一致的值。是的,它在很多情况下有效,但在其他情况下则无效。Stephen C 2015-08-22
嗯,javac -classpath . HelloWorld.java 肯定会起作用!对于您的情况来说,这是一个更好的解决方案。Stephen C 2015-08-22
如果您将“package com.some.address”作为第一行 - 这将不起作用。您需要注释掉“包地址”。Joe 2018-03-12
@Joe - 这个 hack(注释掉包)会起作用(在某些情况下),但这是一个坏主意。更好的想法是了解/理解导致问题的原因并实施正确的解决方案。Stephen C 2019-04-26
取消设置类路径变量基本上对我有用。Amila Weerasinghe 2020-12-11
#6楼
得票数 43

在命令行上指定类路径对我很有帮助。例如:

  1. 创建一个新文件夹C:\temp

  2. C:\temp中创建文件Temp.java,其中包含以下类:

     public class Temp {
         public static void main(String args[]) {
             System.out.println(args[0]);
         }
     }
    
  3. 在文件夹C:\temp中打开命令行,并编写以下命令来编译Temp类:

     javac Temp.java
    
  4. 运行编译后的 Java 类,添加 -classpath 选项让 JRE 知道在哪里可以找到该类:

     java -classpath C:\temp Temp Hello!
    
Celebes 提问于2014-07-02
Peter Mortensen 修改于2022-02-02
在 Ubuntu 中,我还必须指定路径。不明白为什么它默认不能使用当前工作目录。我确信 Java 是由Keyboard制造商赞助的!!gone 2014-09-30
@gone - “.”的原因默认情况下不在 $PATH 中是因为它是一个安全陷阱。 seas.upenn.edu/cets/answers/dot-path.htmlStephen C 2015-06-30
非常感谢......尽管不知道为什么java即使在环境变量中设置它之后也无法找到类路径。akash89 2015-09-01
@akash89 - 最可能的原因是:1)java 没有查看 $CLASSPATH(因为您使用了 -classpath 或 -jar)或 2)未在不存在的环境中设置类路径设置在运行 java 的上下文中产生效果;例如因为您没有“获取”在正确的 shell 中添加 setenv 命令的文件。Stephen C 2016-03-15
我仍然收到错误:无法找到或加载主类 Temp 任何人都可以帮忙!Alaa Jabre 2017-05-28
#7楼
得票数 29

根据错误消息(“Could not find or load main class”),有两类问题:

  1. 无法找到主类
  2. 主类无法加载(这种情况在接受的答案中没有充分讨论)

完全限定的类名中存在拼写错误或语法错误或者在提供的类路径中不存在时,无法找到主类。

类无法启动时,无法加载主类。通常,主类扩展另一个类,并且该类不存在于提供的类路径中。

例如:

public class YourMain extends org.apache.camel.spring.Main

如果不包含camel-spring,就会报这个错误。

Devs love ZenUML 提问于2015-09-17
Peter Mortensen 修改于2022-02-02
“基本上”还有很多其他类别。缺少超类问题是一个非常不寻常的子情况。 (如此不寻常,以至于我从未在该网站上提出的问题中见过它。)Stephen C 2015-09-17
有两个,因为错误显示"Could not FIND or LOAD main class"。如果还有其他类别,请告诉我。我已经看到了,所以只是想在这里分享,也许其他人会需要它。Devs love ZenUML 2015-09-17
我会将其修改为“您需要包含启动主类所需的所有类以避免此特定错误”。我并不是想说服你。这只是我希望看到的一种方式。我把答案留在这里只是为了那些可能喜欢以这种方式阅读东西的人。让我们不要进一步扩展这个讨论:)我将我的声明更改为“在接受的答案中未充分讨论”并希望您感觉好一些。Devs love ZenUML 2015-09-17
此信息至关重要,值得明确提及(这是唯一提及extends的答案)。我刚刚经历了惨痛的教训,当主类由于扩展了另一个无法找到的类而无法加载时,java 不会报告哪个实际类是未找到(与NoClassDefFoundError不同)。所以,是的,它确实发生了,而且当你不知道这一点时,这是一个令人烦恼的情况。Hugues M. 2017-05-31
在这种情况下,有什么方法可以准确判断哪个依赖类无法加载?Carlos A. Ibarra 2018-03-02
#8楼
得票数 23

使用这个命令:

java -cp . [PACKAGE.]CLASSNAME

示例:如果您的类名是从 Hello.java 创建的 Hello.class,则使用以下命令:

java -cp . Hello

如果您的文件 Hello.java 位于 com.demo 包内,则使用以下命令

java -cp . com.demo.Hello

使用 JDK 8 很多时候,类文件出现在同一个文件夹中,但 java 命令需要类路径,因此我们添加 -cp . 以将当前文件夹作为参考类路径。

shaILU 提问于2017-02-23
Peter Mortensen 修改于2018-02-06
这只适用于简单的情况。更复杂的情况需要更复杂的类路径。Stephen C 2017-02-23
而对于 >>真正<< 简单的情况,则无需使用-cp .,因为如果未设置 $CLASSPATH.就是默认的 classpath。Stephen C 2017-03-07
不,Stephen,很多时候在 Windows 中默认类路径不起作用。我在三台不同的机器上尝试过,你也可以尝试一下。shaILU 2017-05-05
这可能是因为您实际上在某处设置了 %CLASSPATH% 环境变量。如果您这样做,那么您就没有使用默认的类路径。 (echo %CLASSPATH% 输出什么?)不,我无法检查,因为我没有 Windows PC。Stephen C 2017-05-05
当我尝试从命令行运行一个简单的程序时,这对我有用SnuKies 2019-07-09
#9楼
得票数 21

我在这种情况下遇到了这样的错误:

java -cp lib.jar com.mypackage.Main

它适用于 Windows 的 ; 和 Unix 的 :

java -cp lib.jar; com.mypackage.Main
Yamahar1sp 提问于2016-09-22
Peter Mortensen 修改于2017-04-09
是的。这很可能是因为您的 Main 不在 JAR 文件中。 -cp lib.jar;-cp lib.jar;. 含义相同,即当前目录包含在类路径中。Stephen C 2016-09-22
终于解决了 unix 的问题..谢谢(适用于:)Vicky 2019-01-24
#10楼
得票数 21

尝试-Xdiag

Steve C 的回答 很好地涵盖了可能的情况,但有时确定类是否无法找到加载可能并不那么容易。使用java -Xdiag(自 JDK 7 起)。这会打印出一个很好的堆栈跟踪,它提供了消息 Could not find or load main class 消息含义的提示。

例如,它可以向您指出主类使用的其他类无法找到并阻止加载主类。

jan.supol 提问于2016-08-24
Peter Mortensen 修改于2018-02-06
#11楼
得票数 16

有时,导致问题的原因可能与主类无关,我就是通过这种艰难的方式发现这一点的。我移动了一个引用库,结果出现了以下问题:

Could not find or load main class xxx Linux

我刚刚删除了该引用,然后再次添加它,并且它再次正常工作。

Eddie Martinez 提问于2013-11-01
Peter Mortensen 修改于2017-01-14
听起来问题在于您的 IDE 项目中的“引用”损坏,导致您的类路径不正确。我将更新我的答案以涵盖该案例。Stephen C 2013-11-02
@StephenC 和 EduardoDennis,这里也缺少一个 jar,该 jar 包含一个主类依赖于实例化的接口。因此,错误消息过于宽泛。如果找不到类文件,我应该说“无法找到”;如果缺少其他内容而不是文件本身,我应该说“无法加载(缺少依赖项)”,因此如果您只关注的话,错误消息太宽泛会产生误导关于它的“查找”部分:(Aquarius Power 2016-11-07
@AquariusPower - 应该有一个额外的“由”堆栈跟踪来表示“原因”异常,该异常表示缺少什么类。如果您想建议 Java 开发人员更改一条已显示 20 多年的错误消息……请随意。 (我认为错误消息是正确的。问题是 >>you<< 缩小了错误的子句范围。)Stephen C 2016-11-07
@StephenC 我的意思是,如果主类文件可用或不可用,他们肯定可以访问信息,所以为什么不向我们显示更好的错误消息,说明此类文件丢失。另一方面,他们也可能会说“文件已找到,但无法加载”,此时我们会立即关注依赖项,而不是浪费半天时间研究和测试要理解的东西。这就是我的意思:)。他们可能会以有限的方式做20多年,但他们可以改进它,我们在这里通过我们的批评和投诉承认这将会发生! :DAquarius Power 2016-11-08
请理解>>我<<的意思。在 3 年前的问答中发表一些晦涩的评论来抱怨它不会取得任何成果。可能会对您的投诉采取行动的人不会注意到这一点。如果您想做一些有建设性的事情,请提交补丁。 (我不会评价你的机会,但机会会比你只是抱怨的机会更大。)Stephen C 2016-11-08
#12楼
得票数 13

我遇到了同样的问题,终于发现了我的错误:) 我使用这个命令进行编译并且它工作正常:

javac -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar" qrcode.java

但这个命令对我不起作用(我无法找到或加载主类,qrcode):

java -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar" qrcode

最后我只是在类路径末尾添加了“:”字符,问题就解决了:

java -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar:" qrcode
Omid Mohebbi 提问于2019-03-18
Peter Mortensen 修改于2019-09-12
#13楼
得票数 10

在这种情况下,您有:

Could not find or load main class?classpath

这是因为您使用的是“-classpath”,但破折号与命令提示符上java使用的破折号不同。我在从 记事本 复制并粘贴到 cmd 时遇到此问题。

Nathan Williams 提问于2015-06-30
Peter Mortensen 修改于2017-01-14
哇!这实在是一个非常奇怪的原因! (但它适合您使用记事本而不是真正的文本编辑器:-))Stephen C 2015-06-30
#14楼
得票数 10

如果您使用 Maven 构建 JAR 文件,请确保在 pom.xml 中指定主类:

<build>
    <plugins>
        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>class name us.com.test.abc.MyMainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>
Junchen Liu 提问于2017-06-15
Peter Mortensen 修改于2018-02-06
#15楼
得票数 9

就我而言,出现错误是因为我提供了源文件名而不是类名。

我们需要向解释器提供包含 main 方法的类名。

KawaiKx 提问于2014-03-12
Peter Mortensen 修改于2022-02-02
是的。请参阅我的示例#2,了解指定类名的错误方法!Stephen C 2014-03-12
#16楼
得票数 9

Enter image description here

类文件位置: C:\test\com\company

文件名: Main.class

完全限定类名: com.company.Main

命令行命令:

java  -classpath "C:\test" com.company.Main

请注意,类路径包含\com\company

developer747 提问于2017-03-26
Peter Mortensen 修改于2022-02-02
#17楼
得票数 8

这里的所有答案似乎都是针对 Windows 用户的。对于 Mac,类路径分隔符是 :,而不是 ;。由于不会抛出使用 ; 设置类路径的错误,因此如果从 Windows 到 Mac,这可能很难发现。

这是对应的Mac命令:

java -classpath ".:./lib/*" com.test.MyClass

在此示例中,包为 com.test,并且 lib 文件夹也将包含在类路径中。

blue-sky 提问于2016-10-04
Peter Mortensen 修改于2017-01-20
在 Linux 上就像在 Mac 上一样。Alex78191 2017-10-04
为什么/*是必要的?Alex78191 2017-10-04
它是一种通配符语法。 (这不是强制性的。如果您愿意,您可以明确列出 JAR。)Stephen C 2019-05-21
#18楼
得票数 8

如果您的情况与我的情况特别相似,这可能会对您有所帮助:作为初学者,当我尝试运行 Java 程序时,我也遇到了这个问题。

我是这样编译的:

javac HelloWorld.java

我也尝试使用相同的扩展名运行:

java Helloworld.java

当我删除.java并重写命令如java HelloWorld时,程序运行完美。 :)

Ramesh Pareek 提问于2017-06-01
Peter Mortensen 修改于2018-02-06
这是因为您正在执行 .java 的编译版本。它实际上是在执行.class文件Jason V 2017-09-20
根据记录,这与我的答案中的原因 #1、示例 #5 相同......Stephen C 2017-10-30
#19楼
得票数 7

我认为我以某种方式错误地设置了类路径,但问题是我输入了:

java -cp C:/java/MyClasses C:/java/MyClasses/utilities/myapp/Cool  

代替:

java -cp C:/java/MyClasses utilities/myapp/Cool   

我认为完全限定的含义意味着包含完整路径名而不是完整包名。

mathewbruens 提问于2015-09-02
Peter Mortensen 修改于2022-02-02
我已经更新了我的答案以尝试解决这种困惑。Stephen C 2015-09-02
这些都不正确。该类必须以 utilities.myapp.Cool 或其包名称(如果有)的形式给出。user207421 2018-02-07
#20楼
得票数 6

当使用 Windows PowerShell 中的 -cp 选项运行 java 时,您可能会收到类似于以下内容的错误:

The term `ClassName` is not recognized as the name of a cmdlet, function, script ...

为了让 PowerShell 接受该命令,-cp 选项的参数必须包含在引号中,如下所示:

java -cp 'someDependency.jar;.' ClassName

以这种方式形成命令应该允许 Java 正确处理类路径参数。

Chezzwizz 提问于2017-05-21
Chezzwizz 修改于2017-05-21
#21楼
得票数 5

在 Windows 上,将 .; 放在 CLASSPATH 值的开头。

.(点)表示“在当前目录中查找”。这是一个永久的解决方案。

您也可以使用 set CLASSPATH=%CLASSPATH%;. 将其设置为“一次”。只要您的 cmd 窗口打开,该状态就会持续。

Nenad Bulatović 提问于2015-10-24
Peter Mortensen 修改于2017-01-20
这个建议可能有帮助,也可能没有帮助。如果类树包含当前目录中的类,它将有所帮助。如果他们不是,那就不会。我其实不会这样做。相反,我会创建一个单行包装脚本,无论用户是否位于“正确”目录中,该脚本都可以工作。Stephen C 2015-11-08
#22楼
得票数 5

这是一个具体案例:

Windows(使用 Windows 7 进行测试)不接受以下格式的特殊字符(例如 á)类和包名称。但 Linux 确实如此。

当我在 NetBeans 中构建 .jar 并尝试在命令中运行它时,我发现了这一点。它在 NetBeans 中运行,但不在命令行上运行。

GuiRitter 提问于2015-12-27
Peter Mortensen 修改于2022-02-02
#23楼
得票数 5

解决我的问题的方法是:

右键单击要运行的项目/类,然后选择“运行方式”→“运行配置”。然后您应该修复现有配置或通过以下方式添加新配置:

打开类路径选项卡,单击高级...按钮,然后添加项目的bin文件夹

syntagma 提问于2016-01-16
Peter Mortensen 修改于2022-02-02
#24楼
得票数 4

首先使用此命令设置路径;

set path="paste the set path address"

然后你需要加载程序。在存储的驱动器中输入“cd(文件夹名称)”并编译。例如,如果我的程序存储在D驱动器上,则输入“D:”按回车键并输入“cd(文件夹名称)”。

arun 提问于2013-12-02
Louis van Tonder 修改于2013-12-02
这没有帮助。这个问题是关于Java程序,而不是普通的可执行文件。 Java 不使用 PATH 来定位任何东西,如果“cd”有帮助,那么它是运气好而不是判断。Stephen C 2013-12-02
if "cd" helps then it by luck rather than by judgement。这是错误的(我相信),因为 java 默认使用当前目录 . 作为类路径的一部分。GKFX 2014-03-31
@GKFX - 这就是我的意思。除非您知道您正在使用默认的类路径(或带有“.”的类路径),否则“cd”将不起作用。这个解决方案更多地靠运气(即猜测/希望“.”在类路径上)而不是通过判断(即检查“.”在类路径上)。此外,您对默认值的看法是不正确的。 Java 使用“.”默认情况下作为类路径,而不是默认情况下作为类路径的一部分。Stephen C 2014-06-12
大概是在 Windows 上?Peter Mortensen 2022-02-02
#25楼
得票数 4

在 Java 中,当您有时使用 Java 解释器可执行文件从命令行运行 JVM 并尝试使用 public static void main (PSVM) 从类文件启动程序时,您可能会遇到以下错误,即使类路径参数为JVM 是准确的,并且类文件存在于类路径中:

Error: main class not found or loaded

如果无法加载带有 PSVM 的类文件,就会发生这种情况。一个可能的原因是该类可能正在实现一个接口或扩展不在类路径上的另一个类。通常,如果类不在类路径上,则抛出的错误会指出这一点。但是,如果正在使用的类被扩展或实现,Java 就无法加载该类本身。

参考: https://www.computingnotes.net /java/error-main-class-not-found-or-loaded/

Anandaraja Ravi 提问于2015-09-18
Peter Mortensen 修改于2022-02-02
您阅读了接受的答案吗?你的回答有什么新的内容吗?Stephen C 2015-09-18
@StephenC我试图通过查看“原因”类别及其要点来在您的列表中找到原因。我找不到“原因#1”中的匹配点,而“原因#2”标题看起来与我的情况不太接近(因为我确信类路径本身没有问题)。我通过执行实验找到了原因,令我惊讶的是,在我的例子中,由于实现接口不在类路径上,所以显示“main class not found”错误。当然,您可以说“您应该阅读帖子中描述的所有内容”,但在我看来您的原因列表可以改进。humkins 2017-06-22
链接已损坏:“嗯。我们找不到该站点。我们无法连接到 www.computingnotes.net 上的服务器。”Peter Mortensen 2022-02-02
#26楼
得票数 4

您确实需要从 src 文件夹执行此操作。您可以在其中键入以下命令行:

[name of the package].[Class Name] [arguments]

假设您的类名为CommandLine.class,代码如下所示:

package com.tutorialspoint.java;

    /**
     * Created by mda21185 on 15-6-2016.
     */

    public class CommandLine {
        public static void main(String args[]){
            for(int i=0; i<args.length; i++){
                System.out.println("args[" + i + "]: " + args[i]);
            }
        }
    }

然后你应该 cd 到 src 文件夹,你需要运行的命令如下所示:

java com.tutorialspoint.java.CommandLine this is a command line 200 -100

命令行上的输出将是:

args[0]: this
args[1]: is
args[2]: a
args[3]: command
args[4]: line
args[5]: 200
args[6]: -100
Marco V 提问于2016-06-15
Peter Mortensen 修改于2022-02-02
类不能称为“CommandLine.class”。那将是一个 Java 语法错误。 (您的意思是包含编译类的文件称为“CommandLine.class”...)。另一个问题是,只有当您将代码编译到 << 源目录树时,“cd 到源目录”的指令才有效。最后,如果您的编译使用了“-cp”参数,那么在运行时您需要一个等效的参数。Stephen C 2016-07-25
在我的项目中,我的根目录下有 src 文件夹和 bin 文件夹。我必须cd进入src,然后运行对我有用的命令java ../bin com.blah.blah.MyClass。所以谢谢你的提示!tamj0rd2 2017-07-21
#27楼
得票数 4

我在测试 Java MongoDB JDBC 连接时也遇到了类似的错误。我认为简短地总结我的最终解决方案是很好的,以便将来任何人都可以直接查看这两个命令,并有利于进一步进行。

假设您位于 Java 文件和外部依赖项(JAR 文件)所在的目录中。

编译:

javac -cp mongo-java-driver-3.4.1.jar JavaMongoDBConnection.java
  • -cp - 类路径参数;将所有依赖的JAR文件一一传递
  • *.java - 这是具有 main 方法的 Java 类文件。 SDSD

运行:

java -cp mongo-java-driver-3.4.1.jar: JavaMongoDBConnection
  • 所有依赖 JAR 文件结束后,请务必遵守冒号 (Unix)/逗号 (Windows)
  • 最后,观察没有任何扩展名的主类名称(没有 .class 或 .java)
khichar.anil 提问于2018-01-26
Peter Mortensen 修改于2022-02-02
这一切都假设 1) JavaMongoDBConnection 没有软件包,2) 您不更改目录。至少可以说,它是脆弱的。如果不解释问题,就会导致新手在不起作用的情况下尝试这种方法。简而言之,它鼓励“巫毒编程技术”:en.wikipedia.org/wiki/Voodoo_programmingStephen C 2018-01-27
#28楼
得票数 3

好吧,已经有很多答案了,但没有人提到文件权限可能是罪魁祸首的情况。

运行时,用户可能无权访问 JAR 文件或路径的目录之一。例如,考虑:

/dir1/dir2/dir3/myjar.jar 中的 jar 文件

拥有 JAR 文件的 User1 可以执行以下操作:

# Running as User1
cd /dir1/dir2/dir3/
chmod +r myjar.jar

但它仍然不起作用:

# Running as User2
java -cp "/dir1/dir2/dir3:/dir1/dir2/javalibs" MyProgram
Error: Could not find or load main class MyProgram

这是因为运行用户 (User2) 无权访问 dir1、dir2、javalibs 或 dir3。当 User1 可以看到这些文件并可以访问这些文件时,可能会让人抓狂,但 User2 仍然会发生错误。

biocyberman 提问于2018-09-26
Peter Mortensen 修改于2019-09-12
#29楼
得票数 2

我无法用此处所述的解决方案解决这个问题(尽管所述答案无疑已经澄清了我的概念)。我遇到这个问题两次,每次我都尝试不同的解决方案(在 Eclipse IDE 中)。

  • 首先,我在项目的不同类中遇到了多个 main 方法。因此,我从后续类中删除了 main 方法。
  • 其次,我尝试了以下解决方案:
    1. 右键单击我的主项目目录。
    2. 前往源代码,然后进行清理并坚持使用默认设置,然后单击“完成”。完成一些后台任务后,您将被引导到主项目目录。
    3. 之后我关闭我的项目,重新打开它,然后,我终于解决了我的问题。
Anus Kaleem 提问于2016-06-04
Peter Mortensen 修改于2017-01-20
删除 main 方法不会解决问题。具有多个入口点的应用程序在技术上没有任何问题。Stephen C 2017-01-27
#30楼
得票数 2

有时,在您可能尝试过的某些在线编译器中,如果您不写public class [Classname]而只写class [Classname],则会收到此错误。

lor 提问于2017-08-18
请举例(有问题的编译器)。虽然创建“入口点”类 public 是常规/正常的做法,但 Java 规范并不要求这样做,标准 Oracle / OpenJDK java 命令也没有要求。Stephen C 2018-07-23
#31楼
得票数 2

就我而言,我收到错误是因为我在 Windows 7 系统上混合了大小写包名称。将包名称更改为全部小写解决了该问题。 另请注意,在这种情况下,我将 .java 文件编译为 .class 文件时没有出现错误;它只是不会从同一个(子子子子)目录运行。

Howard007 提问于2017-12-26
#32楼
得票数 2

我有一个奇怪的:

Error: Could not find or load main class mypackage.App

事实证明,我在项目的 pom.xml 文件中编码了 POM (父级)的引用(我的项目的 pom.xml 指向父级 pom.xml),而 relativePath 已关闭/错误的。

以下是我的项目的pom.xml文件的一部分:

<parent>
    <groupId>myGroupId</groupId>
    <artifactId>pom-parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <relativePath>../badPathHere/pom.xml</relativePath>
</parent>

一旦我解析了 POMrelativePath,错误就消失了。

去搞清楚。

granadaCoder 提问于2018-07-23
granadaCoder 修改于2019-09-12
#33楼
得票数 2

这是另一个花了我一些时间的问题:命令行类路径参数的行为不符合您的预期。我在 MacOS 上直接调用 CLI,并且在调用中包含两个 jar。

例如,这两个都使工具对主类的名称感到困惑:

这是因为星号导致它错误地解析参数:

java -cp path/to/jars/* com.mypackage.Main

这是因为——我不知道为什么:

java -cp "*.jar" com.mypackage.Main

这有效:

java -cp "path/to/jars/*" com.mypackage.Main

明确列出两个 jar 也有效:

java -cp path/to/jars/jar1.jar:path/to/jars/jar2.jar com.mypackage.Main

Nikolay Valtchanov 提问于2019-11-26
“我不确定为什么” - 因为 * 由 shell 扩展为 JAR 文件名列表 用空格分隔 ...除非用引号引起来。这是标准的 UNIX shell 内容。至于其余的:包括:和通配符语法("path/to/jars/*")的使用,都在java手册条目中。Stephen C 2019-11-27
那是“不确定为什么“*.jar”不起作用”。第一个更清楚,因为shell弄乱了它。Nikolay Valtchanov 2019-11-28
第二个不起作用,因为 java 命令不理解该通配符。 java 手册解释了它所理解的内容。Stephen C 2019-11-28
#34楼
得票数 2

经过两天的搜索,我找到了这个解决方案并且有效。这很奇怪,但对我有用。

package javaapplication3;
public class JavaApplication3 {

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    // TODO code application logic here
    System.out.println("Hello");
}

}

这是我想要运行的程序,位于 C:\Java Projects\JavaApplication3\src\javaapplication3

现在在此位置打开 cmd 并使用此命令编译程序

javac JavaApplication3.java

编译后,向下导航一个目录,即 C:\Java Projects\JavaApplication3\src

现在运行以下命令来执行程序

java javaapplication3.JavaApplication3
Vishv Shroff 提问于2020-09-17
Vishv Shroff 修改于2020-09-17
如果这对您有用,那么您的源代码必须有一个未包含在答案中的 package javaapplication3; 语句。Stephen C 2020-09-17
@StephenC哦,我很抱歉我会更新我的答案。Vishv Shroff 2020-09-17
现在它的内容与 stackoverflow.com/a/26587225/139985 (从 2014 年开始)基本相同Stephen C 2021-01-22
#35楼
得票数 2

场景:使用命令提示符(Windows 中的CMD)来编译运行一个简单的“java”程序,该程序具有仅具有指定“package main”的“Main.java”文件。

源文件路径:

某些项目名称文件夹\src\main\Main.java

目标文件夹:

某些项目名称文件夹\dest

目标文件路径(文件夹“\main”和文件“\Main.class”将由“javac”生成):

一些项目名称文件夹\dest\main\Main.class

Main.java如下:

package main;

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

编译:

// 'javac' compiler will produce 'Main.class' in the 'dest\main' folder.
// 'main' folder is created because in the source file(in our case: 'Main.java') is
// specified 'package main'.

javac -d ./dest ./src/main/Main.java

运行编译后的文件(在我们的例子中:“Main.class”):

// '-cp'(is the same as '-classpath')
// './dest'(means destination folder, where resides compiled 'Main.class').
// 'main.Main'(means 'package' 'main', which contains class 'Main'('Main.class'))
// WARNING: when run 'java' class, MUST NOT type extension '.class'
//          after 'class name
//          (in our case: 'main.Main'(<package>.<class-name>) WITHOUT extension 
//           '.class').

java -cp ./dest main.Main

// Hello world
Ted 提问于2020-09-19
Ted 修改于2020-09-19
stackoverflow.com/a/26587225/139985 说同样的话(从 2014 年开始)Stephen C 2021-01-22
#36楼
得票数 2

我在执行mvn eclipse:eclipse后收到此错误。这有点搞乱了我的.classpath 文件。

我必须将.classpath中的行从

<classpathentry kind="src" path="src/main/java" including="**/*.java"/>
<classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>

<classpathentry kind="src" path="src/main/java" output="target/classes" />
<classpathentry kind="src" path="src/main/resources" excluding="**"  output="target/classes" />
Jaanus 提问于2015-12-14
Peter Mortensen 修改于2022-02-02
“mvn”应该做什么?与 Maven 相关吗?Peter Mortensen 2022-02-02
#37楼
得票数 2

我上升了一级。所以,现在 HelloWorld.class 文件位于 hello\HelloWorld.class 中,我运行了以下命令。其中cp是类路径,.表示仅检查当前目录。

java -cp . hello.HelloWorld

输出

Hello world!
LOrD_ARaGOrN 提问于2021-09-20
Peter Mortensen 修改于2022-02-02
什么教程?它应该输出 "Hello, World!"(不是"Hello world!"Peter Mortensen 2022-02-02
另外,hello.HelloWorld 区分大小写。因此,如果您的文件夹包名称是 Hello,那么命令将为: java -cp . Hello.HelloWorldPrashanth Pradeep 2022-04-04
这个答案是不完整的。显然,Rishi 试图运行一个带有 package hello; 语句的 HelloWorld 类。 (这是他所做的唯一可行的方法。)Stephen C 2022-07-04
#38楼
得票数 2

到目前为止,在所有答案中,还没有人指出关于应用程序类路径的正确规范的这个严重陷阱:

如果您的应用程序和依赖项在文件系统上打包为 jar,并且您尝试使用 java [options] <mainclass> 变体运行它,那么在 CLASSPATH 中提供目录名称是不够的!您必须添加/*通配符!

文档有点难以捉摸这:

If the class path option isn't used and [CLASSPATH] isn't set, then the user class path consists of the current directory (.).

...

这句话会让你认为默认情况下运行java com.acme.example.Gerbera当前目录中所有需要的jar肯定会起作用。唉,事实并非如此。您需要进一步阅读文档。您需要做的是 CLASSPATH=./* java com.acme.example.Gerbera,或者使用适当的分隔符逐字枚举所有 .jar 文件名。

Uldis Barbans 提问于2023-06-03
#39楼
得票数 1

在 IDE 开发(Eclipse、NetBeans 或其他)的上下文中,您必须配置项目属性以拥有主类,以便您的 IDE 知道主类位于何处,以便在您点击“Play”时执行。

  1. 右键单击您的项目,然后属性
  2. 转到 "运行 "类别,选择 "主类
  3. 点击Run按钮。

Enter image description here

julianm 提问于2017-08-22
Peter Mortensen 修改于2018-02-06
但是,如果您尝试从 IDE 运行没有正确 main 的应用程序,您将不会收到上述错误消息。 (对于某些 IDE,您不需要配置启动器来实现这一点;例如 Eclipse 的 run找到具有 main 方法的类你。Stephen C 2017-08-22
事实上,如果您在没有此设置的情况下运行应用程序,您将在原始问题中收到确切的消息: Could not find or load main class ... 。这就是我写这篇文章的方式:)julianm 2017-08-22
在 Eclipse 中则不会。在 Eclipse 中,如果 IDE 无法识别带有 main 的类,则上下文菜单中不会提供“运行”>“Java 应用程序”选项。Stephen C 2017-08-22
#40楼
得票数 1

这也发生在我身上。就我而言,只有当源代码中存在HttpServlet类时才会发生这种情况(IntelliJ IDEA没有给出编译时错误;servlet包导入得很好,但是在运行时出现了这个main class错误) 。

我设法解决了它。我进入菜单FileProject Structure...:

Enter image description here

然后到Modules:

Enter image description here

servlet 模块附近有一个Provided 范围。我将其更改为Compile

Enter image description here

它成功了!

parsecer 提问于2019-07-10
Peter Mortensen 修改于2019-09-12
#41楼
得票数 1

如果此问题与 Eclipse 相关:

尝试将项目添加到您的类路径中。

见下图:

Enter image description here

这个方法对我有用。

Tunde Pizzle 提问于2018-09-19
Peter Mortensen 修改于2019-09-12
#42楼
得票数 1

如果您使用 IntelliJ 并在从 IDE 运行 main 方法时出现错误,只需确保您的类位于 java 包中,而不是 kotlin在此处输入图像描述

Hayk Kerobyan 提问于2020-06-05
#43楼
得票数 1

[Java版本:11]

如果您使用 Java 11,则无需编译和运行 java 文件。

就这样跑

Java ClassName.java

例子:

class abc{ 
    public static void main(String[] args){
        System.out.println("hello Jarvis ");    
    }
}

现在运行命令

java abc.java

enter image description here

Dupinder Singh 提问于2020-11-04
1)没有回答问题。 2)“java 的替代语法”替代#3。Stephen C 2020-11-04
#44楼
得票数 1

Intellij IDE中选择run/debug>>edit configuration,然后为构建和运行菜单选择适当的JDK

Tohid Makari 提问于2022-06-11
#45楼
得票数 0

默认情况下,Java 使用当前工作目录. 作为默认CLASSPATH。这意味着当您在提示符下键入命令时,例如java MyClass,该命令将被解释为好像您输入了java -cp . MyClass。你看到-cpMyClass之间的那个点了吗? (cp 是较长的 classpath 选项的缩写)

这对于大多数情况来说已经足够了,并且事情似乎工作得很好,直到有一天您尝试将目录添加到CLASSPATH。在大多数情况下,当程序员需要这样做时,他们只需运行set CLASSPATH=path\to\some\dir这样的命令。此命令创建一个名为CLASSPATH的新环境变量,其值为path\to\some\dir,或者如果之前已设置CLASSPATH,则将其值替换为path\to\some\dir

完成此操作后,您现在拥有一个 CLASSPATH 环境变量,并且 Java 不再使用其默认类路径 (.),而是使用您设置的类路径。因此,第二天您打开编辑器,编写一些 java 程序 cd 到您保存它的目录,编译它,并尝试使用命令 java MyClass 运行它,您会看到一个不错的输出: Could not find or load main class ...(如果您的命令之前运行良好并且您现在得到此输出,那么您可能就是这种情况)。

发生的情况是,当您运行命令java MyClass时,Java会在您在CLASSPATH中设置的一个或多个目录中搜索名为MyClass的类文件,而不是您当前的工作目录,因此它找不到您的类文件在那里,因此抱怨。

您需要做的就是再次将.添加到您的类路径中,这可以使用命令set CLASSPATH=%CLASSPATH%;.来完成(注意分号后面的点)。用简单的英语来说,这个命令表示“选择CLASSPATH%CLASSPATH%)的最初值,将.添加到它(;.)并将结果分配回CLASSPATH”。

,您可以再次像往常一样使用命令java MyClass

user6419437 提问于2017-05-12
user207421 修改于2018-01-22
#46楼
得票数 0

解决“Could not Load main class error”

阅读完所有答案后,我发现大多数答案都不适合我。所以我做了一些研究,这就是我得到的结果。仅当步骤 1 不起作用时才尝试此操作。

  1. 尝试安装JRE 32或64。如果不起作用,
  2. 打开转到 C:\Program Files (x86)\JavaC:\Program Files\Java

    • i. 打开jdk 文件夹,然后打开bin 文件夹。
    • ii.复制路径并将其添加到环境变量中。确保使用分号 ; 分隔变量。例如,“C:\Yargato\bin;C:\java\bin;”。如果不这样做,将会导致更多错误。

    • iii. 转到jre文件夹并打开其bin文件夹。

    • iv. 此处搜索rt.jar 文件。我的是:

      C:\Program Files (x86)\Java\jre1.8.0_73\lib\rt.jar 复制并在环境变量下搜索类路径变量 并将其粘贴到那里。

    • v. 现在重新启动 cmd 并尝试再次运行。错误将会消失。
    • vi。我将发布我的 YouTube 视频教程的链接。
Boogie 提问于2018-01-04
Peter Mortensen 修改于2018-02-06
这是巫毒的东西。 %JAVA_HOME\bin% 确实需要位于 %PATH% 上,但这会导致不同的错误。 %JAVA_HOME\lib\rt.jar%不需要添加到类路径中。所有需要它的 JRE 或 JDK 工具都会自动将它添加到 bootclasspath 中。Stephen C 2018-01-04
没有添加的时候会出现这个错误。这就是为什么步骤 1 非常重要。Boogie 2018-01-05
试试吧,因为它现在对我班上的朋友有用Boogie 2018-01-05
我知道您需要安装 Java(废话!)并将其放在您的 %PATH% 中。但如果不这样做,您将收到不同的错误消息。例如“java 不被识别为内部或外部命令”。我再说一遍,您建议的“解决方案”并不能解决>>这个<<问题。Stephen C 2018-01-06
您需要以分号结束最后一个环境变量。在添加新路径之前。即“C:\Yargato\bin;C:\java\bin;C:\Programfiles\java......;也以分号结束Boogie 2018-01-06
#47楼
得票数 0

我在 IntelliJ 中创建的演示程序遇到了这个问题。

解决这个问题有两个关键点:

  1. 程序的包名
  2. 终端/cmd 提示符的当前工作目录

我的演示程序:

package io.rlx.tij.c2;

public class Ex10 {
    public static void main(String[] args) {
        // do something
    }
}

源代码路径:

../projectRoot/src/main/java/io/rlx/tij/c2/Ex10.java
  1. 转到java目录:cd ../projectRoot/src/main/java
  2. 编译为类:javac ./io/rlx/tij/c2/Ex10.java
  3. 运行程序:java io.rlx.tij.c2.Ex10

如果我在../projectRoot/src/main/java/io/rlx/tij/c2中运行程序或者在没有包名的情况下运行它,我将收到此错误:Error: Could not find or load main class

Ryan Luo Xu 提问于2020-05-10
stackoverflow.com/a/26587225/139985 说同样的话(从 2014 年开始)Stephen C 2021-01-22
#48楼
得票数 0
  • IntelliJ IDEA 中,检查您的全局库*和本地库
  • 检查库版本文件pom.xml,可能是旧库
  • 前面的答案中提到了很多可能性,也需要尝试
leonidaa 提问于2020-12-28
Peter Mortensen 修改于2022-02-02
#49楼
得票数 0

就我而言,我的类引用了一个在 Eclipse 外部打开的文件。所以它无法在重新编译时重新生成类。需要确保“问题”选项卡中的所有问题均已清除。

Feng Zhang 提问于2023-07-17
#50楼
得票数 0

对于 Java 17,我必须确保模块中的类之一至少有一个 main 方法。只需添加 main 方法就可以解决问题

Gayathri 提问于2023-09-20
#51楼
得票数 -1

看来当我遇到这个问题时,它是独一无二的。

一旦我删除了文件顶部的包声明,它就完美地工作了。

除此之外,似乎没有任何方法可以在我的机器上运行简单的 HelloWorld.java,无论编译发生在哪个文件夹、CLASSPATH 或 PATH、参数或调用的文件夹中。

Addison 提问于2017-02-23
有很多方法可以让它发挥作用。这一切都归结为>>理解<<如何使用Java类路径机制。请阅读我的答案及其链接到的资源。Stephen C 2017-02-23
如果您将这个“解决方案”推向其逻辑结论,那么您最终会在默认包中声明所有类,这对于大型程序来说是一个非常糟糕的主意。Stephen C 2017-02-23
#52楼
得票数 -1

右键单击该项目。

  1. 选择“打开模块设置”
  2. src文件夹标记为“源”
  3. 转到编辑配置,然后选择您的主类
  4. 单击OKApply按钮

这对我有用。

suneelpervaiz 提问于2019-01-04
Peter Mortensen 修改于2019-09-12
#53楼
得票数 -1

另一种让我摸不着头脑的场景是:

package com.me
Public class Awesome extends AwesomeLibObject {
    ....
    public static void main(String[] argv) {
         System.out.println("YESS0");
    }
}

其中 AwesomeLibObject 是在外部库中定义的类。 我收到了同样令人困惑的错误消息:

Error: Could not find or load main class com.Awesome

解决方法很简单:外部库也必须位于类路径中!

Vitaliy 提问于2020-07-14
原因 #2c - 类路径不正确/缺少依赖项Stephen C 2020-07-14
#54楼
得票数 -1

这基本上意味着不存在静态 main(String[] args) 方法。它应该会自动解决它。如果没有,则说明在制作程序(它没有 main 方法)或打包程序(清单信息不正确)时出现了问题。

这有效

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

这不起作用

public class Hello {
    public Hello() {
        System.out.println("Hello");
    }
}
TheWaterWave222 提问于2022-01-24
这个答案具有误导性。异常+消息可能是由许多不同的原因引起的。它“基本上”不是由一件事引起的。Stephen C 2022-01-24
而且......事实上......如果你的“主”类(示例中的Hello)不包含合适的main方法,你实际上会得到一个不同异常+消息。所以你的答案甚至与问题不符。Stephen C 2022-01-24
#55楼
得票数 -1

修复此问题的最简单方法是在此处重新下载 Maven Apache here: https://maven.apache.org/download.cgi

然后你再次设置你的路径:

Enter image description here

系统变量

将路径放在设置 Apache Maven 文件夹的位置,例如:C:\Program Files\apache-maven-3.8.4\bin

Enter image description here

重新启动终端或 IDE,它应该可以工作了。

它总是对我有用。

Juliano Soder 提问于2021-12-13
Peter Mortensen 修改于2022-02-02
如果你没有运行maven项目,请尝试检查你的java路径,有时如果没有设置java路径,你的程序将无法运行,因为找不到主类。Juliano Soder 2021-12-13
问题不是关于如何让 Maven 运行。Stephen C 2022-11-27
#56楼
得票数 -1

原因#2 - 应用程序的类路径指定不正确。阅读前面链接的三个文档。 (是的...阅读它们!Java 程序员至少了解 Java 类路径机制如何工作的基础知识非常重要。)我想将此文档添加到上面这篇非常好的文章中。

JDK 工具和实用程序 一般信息(文件结构、类路径、类的查找方式、更改) 增强功能(JDK 7 中的增强功能) 标准 JDK 工具和实用程序

https://docs.oracle.com/javase/7/docs/technotes/tools/index.html

https://docs.oracle.com/javase/7/docs/technotes/tools/findingclasses.html

https://docs.oracle.com/javase/7/docs/technotes/tools/windows/classpath.html

Java 启动器如何查找类 了解类路径和包名称

https://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javac.html

Java 中的类加载器 Java 类加载器是 Java 运行时环境的一部分,它将 Java 类动态加载到 Java 虚拟机中。由于类加载器的存在,Java 运行时系统不需要了解文件和文件系统。

Java 类不会一次全部加载到内存中,而是在应用程序需要时才加载到内存中。此时,JRE 调用 Java ClassLoader,这些 ClassLoader 动态地将类加载到内存中。

https://en.wikipedia.org/wiki/Java_Classloader

https://www.geeksforgeeks.org/classloader-in-java/

https://en.wikipedia.org/wiki/Java_virtual_machine

Enter image description here

Enter image description here

Enter image description here

leonidaa 提问于2020-12-28
Peter Mortensen 修改于2022-02-02
谢谢,但不用谢。类加载器层次结构的行为不太可能是造成读者问题的原因。如果您查看原因#2,您会发现它是为了鼓励读者去其他地方获取类路径和相关内容的解释而编写的。我经过深思熟虑后做出了这样做的决定。 (理想情况下应该有另一个规范的问答来描述这些内容。另外,请注意,人们已经在抱怨我对这个问题的回答已经太长了。Stephen C 2021-01-01
#57楼
得票数 -1

对于 Java 的新版本,即 Java18,直至 2022 年。 您只需编写 package 关键字以及包含 java 扩展文件和分号的文件夹名称,如下所示:

package JavaProgramming;

因为我在JavaProgramming文件中有hello.java文件。 注意:在为 java 编写文件夹名称时切勿给出空格。就像Java 编程一样,你必须保持这样的状态: JavaProgramming等;

一个简单的hello world的整个代码结构如下:

package JavaProgramming;

public class hello {
  public static void main(String[] args) {
     System.out.println("Hello java after long time");
      }
    }
Abdur Rehman 提问于2022-06-11
#58楼
得票数 -2

如果您是 Maven 项目

  1. 转到 POM 文件。
  2. 删除所有依赖项。
  3. 保存 POM 文件。
  4. 再次仅导入必要的依赖项。
  5. 保存 POM 文件。

这个问题应该消失。

S Krishna 提问于2019-06-23
Peter Mortensen 修改于2019-09-12
对于大多数人来说,这不太可能导致问题消失。Stephen C 2022-01-24
#59楼
得票数 -2

关于外部库的回答 -

编译:

javac -cp ./<external lib jar>: <program-name>.java

执行:

java -cp ./<external lib jar>: <program-name>

上述方案在 OS X 和 Linux 系统中运行良好。注意类路径中的:

Manish Shukla 提问于2018-09-16
Peter Mortensen 修改于2019-09-12
#60楼
得票数 -2

对于数据库连接,我得到了这个。我刚刚在类路径中添加了以下内容:

export CLASSPATH=<path>/db2jcc4.jar:**./**

在这里,我在最后附加了 ./ ,以便我的类在加载时也能被识别。

现在只需运行:

java ConnectionExample <args>

它工作得很好。

Rahul Raghuvanshi 提问于2017-02-07
Peter Mortensen 修改于2022-02-02
如果您不在编译类的目录中,则会失败。Stephen C 2017-02-23
#61楼
得票数 -2

如果您的包名称为 javatpoint,包名称为 com.javatpoint,类名称为 AnotherOne,则按以下类型编译您的类:

cd C:\Users\JAY GURUDEV\eclipse-workspace\javatpoint\src\com\javatpoint
javac AnotherOne.java

并使用运行这个类

cd C:\Users\JAY GURUDEV\eclipse-workspace\javatpoint\src
java com.javatpoint.AnotherOne

(此处应排除包名称。)

ritu mansata 提问于2022-02-01
Peter Mortensen 修改于2022-02-02
我编辑了您帖子的格式(可执行块),因此请注意您下一篇帖子的格式。另外,与该答案相比,附加值是多少? (同一篇文章) stackoverflow.com/questions/18093928/...Lefteris Xris 2022-02-01
#62楼
得票数 -2

这就是我解决问题的方法。

我注意到,如果您在编译中包含 jar 文件,将当前目录 (./) 添加到类路径会有所帮助。

javac -cp "abc.jar;efg.jar" MyClass.java
java -cp "abc.jar;efg.jar" MyClass

javac -cp "**./**;abc.jar;efg.jar" MyClass.java<br>
java -cp "**./**;abc.jar;efg.jar" MyClass
Shardayyy 提问于2021-01-12
Peter Mortensen 修改于2022-02-02
这应该使差异为零。这两种形式都是有效的 Java,并且它们是等效的。Stephen C 2021-01-12
我将编辑,类路径“./”,产生了最大的区别。Shardayyy 2021-01-13
嗯,是的。错误的类路径是已接受答案的第二个原因。请注意,您的特定修复仅在某些情况下有效。 (例如,它不适用于 MacOS 或 Linux。)Stephen C 2021-01-13
#63楼
得票数 -3

就我而言,我只是更改 Eclipse 中的 JRE。

请找到随附的屏幕截图:

Enter image description here

MiniSu 提问于2018-06-17
Peter Mortensen 修改于2019-09-12
#64楼
得票数 -3

排除以下文件解决了问题。

META-INF/*.SF

META-INF/*.DSA

META-INF/*.RSA

build.gradle中添加以下代码

jar {
    from {
        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
    }
    {
        exclude "META-INF/*.SF"
        exclude "META-INF/*.DSA"
        exclude "META-INF/*.RSA"
    }
    manifest {
        attributes(
                'Main-Class': 'mainclass'
        )
    }
}
SANN3 提问于2021-02-03
为什么它解决了问题?你到底在这里做什么?如果您正在修改签名的 JAR 文件,这看起来就像是一种 hack。请解释一下您实际上在做什么……以便人们可以决定您的“这对我有用”解决方案是否与他们正在做的事情相关。Stephen C 2021-02-04