2010-05-02 122 views
1

我有一个简单类异常运行通过命令行Java代码时

package chapter10; 

public class CompilationTest { 


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

} 

的路径是

Test\src\chapter10\CompilationTest.java 

我成功编译代码到相同的文件夹,我现在有

Test\src\chapter10\CompilationTest.class 

但是,当我尝试从相同的文件夹运行它,我得到这个错误

>java CompilationTest 


Exception in thread "main" java.lang.NoClassDefFoundError: CompilationTest (wrong name: chapter10/CompilationTest) 
     at java.lang.ClassLoader.defineClass1(Native Method) 
     at java.lang.ClassLoader.defineClassCond(Unknown Source) 
     at java.lang.ClassLoader.defineClass(Unknown Source) 
     at java.security.SecureClassLoader.defineClass(Unknown Source) 
     at java.net.URLClassLoader.defineClass(Unknown Source) 
     at java.net.URLClassLoader.access$000(Unknown Source) 
     at java.net.URLClassLoader$1.run(Unknown Source) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at java.net.URLClassLoader.findClass(Unknown Source) 
     at java.lang.ClassLoader.loadClass(Unknown Source) 
     at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) 
     at java.lang.ClassLoader.loadClass(Unknown Source) 
Could not find the main class: CompilationTest. Program will exit. 

当我运行使用java chapter10.PropertiesTest使用

>java chapter10/PropertiesTest 

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

回答

7

类是在chapter10包中。作为从父目录运行它:

java chapter10.CompilationTest 

之所以要到父母是Java正在搜索其CLASSPATH,其中包括当前目录,包含CompilationTest.class文件chapter10目录。您还可以添加src目录的绝对路径到CLASSPATH来达到同样的效果:

set CLASSPATH=C:\...\Test\src 
java chapter10.CompilationTest 

或(显然这是更好的方式)的-cp或-classpath参数添加到Java:

java -cp "C:\...\Test\src" chapter10.CompilationTest 
+0

为什么java想让我先到父目录? – unj2 2010-05-02 04:56:18

+0

我已经给答案添加了一个说明。 – 2010-05-02 05:03:07

+4

'CLASSPATH'环境变量被认为是不好的做法。而是使用'-cp'或'-classpath'参数或只是'.bat' /'.sh'文件。 – BalusC 2010-05-02 05:05:44

4

运行。 Java命令期望完全限定的Java类名,而不是字节码文件的路径名。

Java命令通过查找类路径来查找要加载的类。这是要按顺序搜索的目录或JAR文件的列表。使用的算法大致如下:

  1. 取该类的标准名称,替换“。”。带有适用文件分隔符的字符(例如“/”或“\”),并在末尾附加“.class”。结果是一个路径名。

  2. 对于类路径中的每个条目,查找相对于条目的路径名。

    1. 如果查找成功,则加载相应的文件。
    2. 否则,继续下一个类路径条目。
  3. 如果没有查找成功,则抛出一个ClassNotFoundException

类路径可以使用显式的命令行参数(-cp <path>)来设置,或者它可以从一个CLASSPATH环境变量被拾起。如果没有任何类路径被这些方法设置,则默认的类路径为“。”。假定,其中“。”表示当前目录。

正如@BalusC所说的,最佳做法是使用“-cp”参数或创建包装脚本来启动应用程序。依赖于你的shell的$ CLASSPATH有点不稳定,因为你永远不知道它何时可能被覆盖或重置。

(这是一个简化的说明。它不包括“启动类路径”,类路径中可加载的JAR文件设置,从网址,内/匿名类的处理方式等类加载等)