簡體   English   中英

Java NoClassDefFoundError與繼承的類

[英]Java NoClassDefFoundError with inherited class

我最近開始學習Java,但是遇到一些與NoClassDefFoundError相關的問題。 我曾嘗試從該站點和其他地方研究解決方案,但仍然無法解決它們。 我從Windows 7命令提示符運行帶有CLASSPATH環境變量的程序,而不是為每個程序運行定義它。 設置為C: 為了進行故障排除,我創建了一個具有簡化目錄結構的測試包。

C:\\test ,我有Shape.javaCircle.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();
    }
}

如果我在命令提示符下使用以下操作從C:\\編譯Shape.javaCircle.java

C:\>javac test\Shape.java 
C:\>javac test\Circle.java

然后運行編譯的Circle.class文件,例如

C:\java test\Circle

我得到了我期望的輸出:

Drawing a new shape

但是,如果我從C:\\test內部編譯Shape.javaCircle.java

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.javaCircle.java從文件C:\\test目錄,但在運行C:\\目錄下,它的工作原理。 這會改變什么嗎?

編輯2:經過更多測試,事實證明,只要使用命令java test.Circle,我實際上就可以從C:\\ test目錄中編譯並運行Shape.java和Circle.java文件。 我誤解了JVM查找類的方式。 我現在了解,它在分析包導入語句時使用與編譯器相同的方法。

您可以在系統上的任何位置,只要您具有綁定的類路徑即可。

只有這樣,Java VM才能掃描類路徑,並在包test找到類test.Circle

因此,正確的執行是java test.Circle (總是),並且類路徑需要指向某個具有\\test\\Circle.class東西。 檢查Circle.class是否在您期望的位置。

您的類路徑表示您存儲類的位置。 當您將類路徑設置為c:\\ 因此,當您使用java命令啟動jvm時,它將從c:\\加載所需的類。 當您從C:編譯並運行程序時,您的代碼正在工作,因為在這種情況下,這些類將被編譯並以C:形式出現,所以沒有問題。 但是,當您從c:\\test編譯類時,.class文件將出現在c:\\ test中,但您的類路徑將僅從c:\\而不是c:\\test加載類。

編譯,使用

javac -d . Shape.java
javac -d . Circle.java

跑步

java test.Circle

-d用於選擇目標目錄
. 表示當前目錄,因此在當前Directry C:\\test\\ ,當編譯Java文件時,將創建一個名為test (程序包名稱)的新目錄,並將在其中包含類文件。 即。
C:\\test\\test\\Shape.javaC:\\test\\test\\Circle.java

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM