当前位置: 首页 > 面试题库 >

Java找不到主类

云弘壮
2023-03-14
问题内容

我已经编写了以下Java源文件(Hello.java):

package com;

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

我将此保存到C:/tmpjava/Hello.java

从命令行,我导航到该目录并运行javac Hello.java。然后我运行dir

  • Hello.class
  • Hello.java

然后,从我刚运行过的同一目录javac运行java Hello.class并获取:

Exception in thread "main" java.lang.NoClassDefFoundError: Hello/class
Caused by: java.lang.ClassNotFoundException: Hello.class
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
Could not find the main class: Hello.class.  Program will exit.

这里发生了什么?!?如何javac运行正常,但不能运行java


问题答案:

您的课程Hello属于该包com。因此,您的课程的全限定名是com.Hello。在命令行上使用java调用程序时,应提供包含main方法的类的标准类名,并省略
.class ,如下所示:

java com.Hello

Java程序需要此完全限定的类名来了解您所指的是哪个类。

但是你还有另一个问题。Java程序使用文件系统查找包,子包以及属于它们的类。因此,如果您具有类似的包结构com.Hello,则Java程序希望在名为
com 的目录中找到一个名为 Hello.class 的类文件,如下所示: com / Hello.class
。实际上,您可以在所看到的中观察到这种行为。您错误地使用了 Hello.class ,它被java解释为一个名为的 和一个名为的
,并且正在寻找目录结构 Hello / class Exception Hello class

java.lang.NoClassDefFoundError:您好/类

但是默认情况下,编译器javac 不会
设置此目录结构。请参阅javac的文档,但重要的一点是:进行编译时,可以使用-d标志指定目标目录:

-d目录

设置类文件的目标目录。目标目录必须已经存在;javac将不会创建目标目录。如果类是包的一部分,则javac会将类文件放在反映包名称的子目录中,并根据需要创建目录。例如,如果指定-
dc:\ myclasses且该类称为com.mypackage.MyClass,则该类文件称为c:\ myclasses \ com \
mypackage \ MyClass.class。

如果未指定-d,则javac会将类文件与源文件放在同一目录中。

粗体字的最后一点是给初学者造成很多混乱的根源,并且是您自己的问题的一部分。

因此,您有两种选择:

  1. 就您而言,如果您将当前目录作为目标目录提供就可以了,就像这样(句点.表示 当前目录 ):
    javac -d . Hello.java
    

如果您这样调用编译器,它将为您创建 com 目录,并将已编译的类文件放入其中,这是Java程序期望找到它的方式。然后,当您如上所述运行Java时,应从
c:\ tmpJava 运行程序。

  1. 您可以使用与包结构类似的目录结构来设置源代码:在示例中,将源文件 Hello.java 放在名为 com 的目录中: c:\ tmpJava \ com \ Hello.java 。现在,从 c:\ tmpJava 您可以像这样运行javac编译:
    javac com\Hello.java
    

您没有提供该-d标志,但这很好,因为您自己创建了目录结构,并再次引用了上面的文档:

如果未指定-d,则javac会将类文件与源文件放在同一目录中。

同样,当您如上所述运行Java时,您的程序应执行。

请注意,第二种选择是Java程序员常用的选择:源代码文件以反映包结构的目录结构组织。

在这种解释中,我们忽略了 类路径 的概念。您还需要了解如何编写Java程序,但是在仅在当前目录中编译程序的情况下-
如果在编译类时遵循上述两种选择之一,则无需设置类路径就可以逃脱,默认情况下,Java程序将当前目录作为类路径。另一句话,这是来自Java文档的:

-cp类路径

指定目录,JAR存档和ZIP存档的列表以搜索类文件。类路径条目用分号(;)分隔。指定-classpath或-
cp会覆盖CLASSPATH环境变量的任何设置。

如果未使用-classpath和-cp且未设置CLASSPATH,则用户类路径由当前目录(。)组成。

请注意,当您使用类似Eclipse的IDE来运行Java代码时,通常可以为您解决此问题,但是仍然会遇到类路径问题。



 类似资料:
  • 我编写了以下Java源文件(): 我将其保存到。 null 这是怎么回事?!?如何才能使运行良好,而不能使运行良好?

  • 现在,在你报告这是一个已经被问过的问题之前,听我说完。 我已经看了所有其他问题,没有一个提供答案--我已经试过了所有的问题。此外,它们都至少有一年了,所以我猜答案不再起作用的原因是Netbeans一定已经更新了。 -CoolKat

  • 我遇到了一个问题,找不到主类错误与一个有点复杂的程序,我正在工作。为了消除可能的问题,我决定尝试一个hello world程序,看看我是否能让它发挥作用。我在一个服务器上工作,我很确定它运行的是Red Hat Enterprise6。为了回答这个问题,我遵循了Bart Kiers提供的以下步骤: null 如果我键入java-version,将显示版本信息,这表明我的PATH变量设置正确。有人对可

  • 我还尝试将我的类路径设置为'C:\ProgramFiles\java\jre1.8.0_144\lib\rt.jar',尽管我读到这不是必需的。 从class01.java创建class01.class没有问题 不过,当我尝试运行程序时

  • 我认为这个错误是由于路径或类路径不正确造成的,但是我在下载Eclipse Neon时使用Java几个月没有问题,因为我设置了路径。我还发现在包中也会导致错误,所以我在包外创建了类,但仍然得到了错误。 Windows7上的Path和ClassPath环境变量是: 路径变量名:C:\ProgramFiles\Java\JDK1.8.0_101\bin;C:\ProgramFiles\Java\JRE1

  • 我在安装了OpenJDk 7的Ubuntu 12.04上使用Eclipse 3.7.2 java版本给出 每当我尝试运行项目时,都会收到以下错误。 所有项目都会发生这种情况,我已经在我的 Windows 系统上成功编译了这些项目。而且,当直接从终端使用 javac 和 java 时,它可以工作。有没有简单的解决方案?这是因为OpenJDK吗? 类代码是: 更新:我的源代码在一个名为swingtes