我有一个Main类,其中包含声明到名为mainPkg的程序包中的main()方法。

现在,我使用一个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$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 java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Unknown Source)
        at mainPkg.Main.main(Unknown Source)


但是,如果我进入build / classes / mainPkg /目录(该包),它将无法正常工作,并且出现“无法找到或加载主类”错误消息?

事实上:

 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


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

特纳克斯

最佳答案

如果您在源文件中注意到,则有Main.java的package语句,如下所示

package mainPkg;
public class Main{

}


编译时,您是说我的Main类具有一个名为mainPkg的命名空间。现在,您已经为类定义了名称空间,任何尝试访问Main的尝试都应具有名称空间前缀,例如mainPkg.Main,我们通常将其称为“完全合格的类名”。

在构建/类中并调用java mainPkg.Main时,JVM将首先检查当前目录中是否有mainPkg子文件夹。既然已经存在,它就会进入内部并找到Main,验证完全限定的类名称是否与我们在java命令中给出的名称匹配,如果相同,它将加载您的类并执行main()。

当您从build / classes / mainPkg运行相同的java mainPkg.Main时,这次mainPkg中没有名为mainPkg的子文件夹,因此它将引发您所看到的错误。

希望这是有道理的:)

08-04 21:11