在这种情况下如何解释NoClassDefFoundError?



我对Java很陌生,只想从命令行运行javacjava

我目前的目录内容是:

hmank ~/c/J/naive » ls
HelloWorld.class  HelloWorld.java

HelloWorld.java中的代码是:

hmank ~/c/J/naive » cat HelloWorld.java 
package com.imshuai.javalinux;
public class HelloWorld{
public static void main(String[] args){
System.out.println("Hello, World!");
}
}

我知道我应该先跑javac -d . HelloWorld.java然后跑java com.imshuai.javalinux.HelloWorld.

但是,我想看看如果我直接运行javac HelloWorld.javajava HelloWorld会发生什么!

结果是javac可以编译HelloWorld.java,但是当java HelloWorld运行时出现错误:

java.lang.NoClassDefFoundError: com/imshuai/javalinux/HelloWorld (wrong name: HelloWorld)

我对NoClassDefFoundError感到困惑,因为我在当前目录中定义了HelloWorldjvm必须找到HelloWorld.class并加载它,否则jvm不能没有关于com/imshuai/javalinux/HelloWorld的信息.

事实上,如果我这样做

javac -d . HelloWorld.java
java HelloWorld

我得到了相同的NoClassDefFoundError尽管HelloWorld.class在正确和错误的地方。


在我看来,在上述错误情况下,jvm应该报告class location not match package错误,jvm找到类并且没有合适的位置放置HelloWorld.class以使java HelloWorld运行成功。


更重要的是,你能告诉我为什么jvm决定报告java.lang.NoClassDefFoundErrorwrong name: HelloWorld的含义是什么?

问题出在包组织中,因为您指定了package com.imshuai.javalinux但缺少正确的文件夹结构。

您应该根据包声明将类排列在文件夹中。

javac命令中的-d .使其正常工作,因为它创建包的文件夹结构,而不是将所有.class文件放在根目录中。

因此,如果您运行java com/imshuai/javalinux/HelloWorld则输出Hello, World!并且程序可以正常工作。

另一种解决方案是将该文件夹添加到 java 类路径中。

最新更新