为什么如果我尝试从其包中执行包含 main() 方法的 class,我会收到一条错误消息?

Why if I try to execute a class containing the main() method from within its package I obtain an error message?

我有一个 Main class 包含声明到名为 的包中的 main() 方法mainPkg.

现在我用ANT脚本用Javac进行编译,这个目标:

<target name="compile" depends="clean">

    <mkdir dir="build/classes"/>

    <echo>INTO compile TASK</echo>
    <echo>BASE DIR: ${basedir}</echo>
    <echo>CLASSPATH: ${basedir}\lib\ojdbc6.jar</echo>

    <javac srcdir="src/mainPkg/" destdir="build/classes">

        <classpath>
            <fileset refid="classpath.compile"/>
        </classpath>

    </javac>
</target>

好的,它会在这个目录(位于项目根目录)中创建编译后的 Main.class 文件:build/classes/mainPkg /(最后一个目录有包名)

好的,现在我的疑问是:为什么我进入 build/classes/ 文件夹并在这里执行:

java mainPkg.Main

它有效,事实上我得到了这个输出(在某些时候有一个例外,但这是另一个与我此时所问的问题无关的问题):

C:\Projects\edi-sta\build\classes>java mainPkg.Main
Hello World !!!
0
java.lang.ClassNotFoundException: oracle.jdbc.OracleDriver
        at java.net.URLClassLoader.run(Unknown Source)
        at java.net.URLClassLoader.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 java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Unknown Source)
        at mainPkg.Main.main(Unknown Source)

但是如果我进入 build/classes/mainPkg/ 目录(包)它不起作用,我得到一个 "impossible to find or load main class"错误信息?

事实上:

 Directory di C:\Projects\edi-sta\build\classes\mainPkg

12/02/2015  17:39    <DIR>          .
12/02/2015  17:39    <DIR>          ..
12/02/2015  17:39             1.190 Main.class
               1 File          1.190 byte
               2 Directory   8.091.906.048 byte disponibili

C:\Projects\edi-sta\build\classes\mainPkg>java Main
Errore: impossibile trovare o caricare la classe principale Main

你能解释一下为什么会这样吗?

Tnx

it works, infact I obtain this output (at certain times there is an exception but this is another problem not related at what I am asking at this time):

虽然这不是您问题的 objective,但出现异常是因为 oracle 驱动程序 jar 文件不在 class 路径中。要修复错误,请使用 -cp 选项将 jar 文件 ojdbc6.jar 添加到 class 路径。

But if I enter into the build/classes/mainPkg/ directory (the package) it don't works and I obtain an "impossible to find or load main class" error message?

mainPkg.Main 是您的 java class 的完全限定名称。您需要将其提供给 java 运行 时间环境,以便它可以找到 运行 class。仅 Main 是不够的,因为 class 路径中可能有许多 java 文件 class 名称 Main.

documentation

中提供了更多信息

By default, the first argument without an option is the name of the class to be called. A fully qualified class name should be used.

如果您在源文件中注意到,Main.java 有这样的包语句

package mainPkg;
public class Main{

}

编译时,您是在说我的 Main class 有一个名为 mainPkg 的命名空间。现在您已经为您的 class 定义了一个命名空间,任何访问 Main 的尝试都应该有像 mainPkg.Main 这样的命名空间前缀,我们通常将其称为完全限定的 Class 名称。

当您在build/classes 并调用java mainPkg.Main 时,JVM 将首先检查当前目录中是否有mainPkg 子文件夹。因为它已经在那里,它会进入并找到 Main,验证完全限定的 class 名称是否与我们在 java 命令中提供的匹配,如果相同,它将加载您的 class 并执行您的 main()。

当你运行来自build/classes/mainPkg的java mainPkg.Main时,这次mainPkg中没有名为mainPkg的子文件夹,所以它会抛出你的错误看到了。

希望这是有道理的:)