我有一个 Main 类,其中包含声明在名为 mainPkg 的包中的 main()方法。
现在我使用ANT脚本用Javac执行编译,这个tartget:
<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 / 目录(包),它就不起作用,我得到&#34;无法找到或加载主要课程&#34; 错误消息?
逸岸:
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
答案 0 :(得分:2)
它有效,事实上我得到了这个输出(在某些时候有一个 异常,但这是另一个与我所要求的无关的问题 此时):
虽然这不是您问题的目标,但是发生异常是因为oracle驱动程序jar文件不在类路径中。要修复错误,请使用ojdbc6.jar
选项将jar文件-cp
添加到类路径中。
但是如果我进入build / classes / mainPkg /目录(包) 它不起作用,我获得“无法找到或加载主类” 错误消息?
mainPkg.Main
是java类的完全限定名。您需要将它提供给Java运行时环境,以便它可以找到并运行该类。仅Main
是不够的,因为类路径中可能有许多带有类名Main
的java文件。
默认情况下,没有选项的第一个参数是 要调用的类。应使用完全限定的类名。
答案 1 :(得分:2)
如果您在源文件中注意到,那么Main.java的包语句就像这样
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的子文件夹,因此它会抛出您错误的错误#39重看。
希望这是有道理的:)