如何在命令提示符下运行属于包的 .class 文件?

42

当我把我的 .class 放在一个 package 中并尝试从 cmd 运行它时,我一直收到错误提示。

这是经过使用 javac 编译后能够工作的代码:

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

然后是不起作用的代码:

package com;

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

在尝试通过命令 java HelloWorld 运行程序后,出现了以下错误:
Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld (wrong nam
e: com/HelloWorld)
    at java.lang.ClassLoader.defineClass1(Native Method)
    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$100(Unknown Source)
    at java.net.URLClassLoader$1.run(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)
    at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)

以下是我目前尝试过的:

java -cp . HelloWorld
java -cp . com.HelloWorld
java -cp . com/HelloWorld
java HelloWorld
java com.HelloWorld
java com/HelloWorld

请记住,javac 没有报错,并且只需删除 package com; 即可解决问题。有时在其他情况下,可能会出现“找不到主类文件”之类的错误信息。

我做错了什么?


2
HelloWorld住在哪里?它住在com/目录下吗? - MadProgrammer
我认为你没有“com”文件夹。 - ihsan kocak
它存储在我创建的目录C:\java中,其中包含HelloWorld.java和HelloWorld.class。 - user2666594
让我尝试将目录重命名为包名,看看会发生什么。 - user2666594
问题现已解决。原来我是在包文件夹内使用java命令,我必须向后cd才能使其正常工作。 - user2666594
13个回答

38

假设您执行了 cd C:/projects 命令并且 HelloWorld.class 文件位于 C:/projects/com 目录下,则只需输入以下命令:

java com.HelloWorld

该文件现在位于C:\com。当我尝试运行您的命令时,它会显示: - user2666594
错误:找不到或无法加载主类com.HelloWorld - user2666594
3
此时必须将工作目录切换到C:\,而不是C:\com。换句话说,您需要尝试从包目录之外运行它。 - sgbj
1
但是为什么要从外部运行呢?如何从内部运行? - Anand Builders

17

软件包与文件的预期目录位置直接相关。

也就是说,如果你有一个带有 package 指令的源文件,比如 com,那么这个文件就应该存储在 com 目录中。

以你的 HelloWorld 例子为例,HelloWorld.java 文件应该被存储在 com 目录下,例如 com\HelloWorld.java

当你编译这个文件时,就会在 com 目录下创建一个名为 HelloWorld.class 的类文件,例如 com\HelloWorld.class

这样,当 Java 查找 com.HelloWorld 类时,它实际上会在其类路径上搜索并将 com\HelloWorld.class 追加到其中,直到找到你的类文件或耗尽类路径为止。

示例

因此,我将你的具有 package 的 HelloWorld.java 示例复制到了 C:\java\com\HelloWord.java

然后从命令行切换到 C:\java 目录...

C:\java>dir com
 Volume in drive C is OS
 Volume Serial Number is ####-####

 Directory of C:\java\com

09/08/2013  01:55 PM    <DIR>          .
09/08/2013  01:55 PM    <DIR>          ..
09/08/2013  01:55 PM               135 HelloWorld.java

接下来我编译了HelloWorld.java

C:\java>javac com\HelloWorld.java

然后我运行了它...

C:\java>java com.HelloWorld
Hello World!

您可能会喜欢阅读Packages教程。


该文件现在位于C:\com。无论我使用“java HelloWorld”还是尝试@sbat建议的“java com.HelloWorld”,问题都是相同的,它无法找到或加载主类。 - user2666594
好的。你尝试过我的例子了吗?你可以把C:\java\com替换为C:\com,因为就像我展示的那样,它能正常工作... - MadProgrammer
有一个错别字。你原本想说的是“现场直播”(live),但是写成了“生活”(life)。 - user763410

4
语法如下:
java -classpath /path/to/package-folder <packageName>.<MainClassName>

所以你可以尝试使用:java com.HelloWorld,默认情况下,类路径指向当前目录(如果未指定),它会期望com/HelloWorld.class文件存在。

如果你在不同的文件夹中,请尝试指定类路径

$ CLASSPATH=/path/to/package-folder/ java com.HelloWorld
Hello World!
$ java -cp /path/to/package-folder/ com.HelloWorld
Hello World!
$ cd /path/to/package-folder/ && java com.HelloWorld
Hello World!

如需进一步解释,请查看:如何运行Java .class文件?


3
当您编译Java代码时,请使用-d选项,对于您的情况,应该是:
javac -d . com.HelloWorld.java

在上述命令完成后,Java编译器会生成一个名为“com”的文件夹,在“com”文件夹下,您将看到您的HelloWorld.class文件。
然后在您运行javac的同一文件夹下,运行以下命令。
java com.HelloWorld

对我来说有效的是:javac -d HelloWorld.java,然后 -> java com.HelloWorld - Combine

3

com目录的父级目录运行程序。

java com.HelloWorld

3
假设文件位于 C:/projects/com/HelloWorld,您可以尝试以下方法。
1. java -cp c:/projects com.HelloWorld 2. cd c:/projects  java com.HelloWorld (例如2在许多情况下不起作用,如Java进程。)
如果没有包声明,将会有一点变化。
1. java -cp c:/projects/com HelloWorld 2. cd c:/projects/com  java HelloWorld (由于相同的原因,这不是很好。)
或者,相对路径也可以,但存在一些风险。 最后记得在cmd的末尾放置类文件。

1

1
在Java文件夹下创建一个名为com的文件夹,并将HelloWorld.java放入com文件夹中。然后再次运行javacjava

0
如果 Java 文件包含 "project",则下降并运行 java 包.class(包名称=父目录名称);否则从同一目录运行(我会说通常是这样)。 # 注意空格等问题,不完美...

package=""
package=`cat $java_file | grep package | awk '{print $2}' | sed 's/;//g'`
path_p="."
[[ ! -z $package ]] && class_p="$package.$class" && path_p=".."   # ;)

cd $path_p
java $class_p

0
在运行Java类时,不需要使用-cp标志;但是在从二进制(jar)文件中运行类或主程序时,则需要使用-cp标志。 在从命令行运行主程序时,您需要确保将类与Java文件中的包名称放置在相同的文件夹结构中,例如。
home/user/foo java com.test.className   

here classNmae class file and exist under home/user/foo/com/test

希望能有所帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接