.java文件中的包使类文件无法使用

时间:2010-10-05 23:23:40

标签: java

自从我上次完成Java以来​​已经太久了,我不记得为什么会发生以下情况:

鉴于此文件由标准Maven项目创建,如下所示:Maven Tutorial

package com.mycompany.app;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
    }
}

编译它,即使使用Maven但使用标准的javac可执行文件,也会生成一个没有错误的类文件。尝试运行类文件,您会收到此错误:

Exception in thread "main" java.lang.NoClassDefFoundError: App (wrong name: com/mycompany/app/App)

删除package命令,再次编译,运行正常。为什么是这样?我正在运行JDK 1.6.0_21顺便提一下。

4 个答案:

答案 0 :(得分:8)

在为类创建package之后,您必须做的一件事是创建嵌套子目录来表示类的包层次结构。在您的情况下,包名称为“com.mycompany.app”,因此App.class(已编译的App.java文件)应驻留在“com / mycompany / app”子目录中。尽管源文件驻留在哪里并不重要。例如,我复制了您的文件并执行了以下操作:

$ ls
App.java
$ javac App.java 
$ ls
App.class       App.java
$ mkdir -p com/mycompany/app
$ mv App.class com/mycompany/app/
$ java com.mycompany.app.App
Hello World!
$ 

请阅读Wikipedia page about Java Packages了解详情。您还可以查看以下链接:

祝你好运!

答案 1 :(得分:0)

这是因为在Java文件系统文件中映射到类(例如,每个公共类必须在一个单独的同名文件中),并且包映射到目录。

因此,如果您有一个com.mycompany.app包中的类,那么它必须位于相对于类路径的com / mycompany / app目录中。

在你的情况下你应该有一个输出目录,比如你应该在/com/mycompany/app/App.java中有这个类。然后构建它,运行javac并将com / mycompany / app / App.java作为参数,而不是com / mycompany / app / App.java。

运行类以类似的方式工作,但是您给出了类的完全限定名,而不是目录路径。

答案 2 :(得分:0)

当您尝试执行程序时,它将使用程序包中指定的路径查找类文件。因此,当您在文件中包含package语句时,您的类文件必须位于com/mycompany/app/目录中(相对于您尝试从中运行它的目录);如果它找不到它,你会得到那个例外。

因此,当您删除该package语句时,JVM将在当前目录中查找它,这就是它工作的原因(因为您在java App所在的同一目录中执行App.java并且存在App.class个文件。)

答案 3 :(得分:0)

您需要将com / mycompany / app文件夹添加到Java CLASSPATH。如果我记得很清楚,你也可以使用参数“-cp”从cmdline中完成。