我最近开始学习 Java,但是我遇到了一些与NoClassDefFoundError. 我试图从这个站点和其他地方研究解决方案,但仍然无法解决它们。我使用设置了 CLASSPATH 环境变量的 Windows 7 命令提示符运行我的程序,而不是为每个程序运行定义它。它设置为C:。为了排除故障,我创建了一个具有简化目录结构的测试包。
在C:\test中,我有Shape.java和Circle.java。Shape.java看起来像这样:
package test;
class Shape {
    void draw() { System.out.println("Drawing a new shape"); }
}
Circle.java看起来像这样:
package test;
public class Circle extends Shape {
        public static void main(String[] args) {
        Circle round = new Circle();
        round.draw();
    }
}
如果我在命令提示符下使用类似的操作Shape.java进行编译Circle.javaC:\
C:\>javac test\Shape.java 
C:\>javac test\Circle.java
并运行编译的Circle.class文件,如
C:\java test\Circle
我得到了我期望的输出:
Drawing a new shape
但是,如果我从内部编译Shape.javaandCircle.javaC:\test
C:\test>javac Shape.java 
C:\test>javac Circle.java
然后尝试Circle.class从任何地方运行
C:\test>java Circle
或者像这样
C:\> java test\Circle
我收到以下错误消息。
Exception in thread "main" java.lang.NoClassDefFoundError: Circle (wrong name: t
est/Circle)
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:792)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:14
2)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:482)
有人可以解释为什么 JAVA 文件是从C:\test文件夹中编译的,但编译后的 Circle 文件会产生该错误吗?我的 CLASSPATH 有问题吗?感谢您的阅读和您希望即将到来的解决方案!
编辑:我做了更多的测试,结果证明如果我从目录编译Shape.java和Circle.java文件但从C:\test目录运行它C:\,它可以工作。这有什么改变吗?
编辑 2:经过更多测试,我实际上可以从 C:\test 目录中编译和运行 Shape.java 和 Circle.java 文件,只要我使用命令 java test.Circle。我误解了 JVM 查找类的方式。我现在明白它在分析包导入语句时使用与编译器相同的方法。