2010-05-02 121 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文件設置,從網址,內/匿名類的處理方式等類加載等)