以下面看这个程序为例(假设该文件的位置是/home/tarena/Test.java):
package a.b;
public class Test
{
public static void main(String[]args)
{
System.out.PRintln("This is a simple test!");
}
}
下面根据不同的编译方法来讨论:
第一种编译方法(此时终端当前目录为主目录):
javac Test.java
假设如果此时终端的当前目录是在/home,则编译命令则应改为:
javac /home/tarena/Test.java
或者使用相对路径:
javac tarena/Test.java
执行完该命令后,在/home/tarena/目录下生成一个Test.class文件.
如何运行这个文件?由于我们只能在包外运行class文件,所以首先要按照包的结构创建目录
mkdir -p a/b
mv Test.class a/b/
然后执行这个class文件(此时终端当前目录为主目录):
java a.b.Test
第二种编译方法(此时终端当前目录为主目录):
javac -d . Test.java
执行该命令后,编译器会根据包结构自动生成相应的目录,对于上面这个程序,则编译生成的class文件位于/home/tarena/a/b/Test.class.由于相应的目录也已经自动生成,并且当前目录恰是包结构的上层目录,所以此时直接执行该文件,不需要再像上面一样手动创建目录:
java a.b.Test
如果编译时-d的参数不是指定的当前目录,假设执行的命令如下(此时终端当前目录为主目录):
javac -d aaa/bbb Test.java
此时,class文件位于/home/tarena/aaa/bbb/a/b/Test.class.此时要执行该class文件有两种方法:
方法1(此时终端当前目录为主目录):
cd aaa/bbb
java a.b.Test
方法2(此时终端当前目录为主目录):
java -cp aaa/bbb a.b.Test
第三种编译方法:
先把源文件按照包结构放到指定的目录中,即首先执行如下命令(此时终端当前目录为主目录):
mkdir -p a/b
mv Test.java a/b/
然后执行如下命令编译这个文件(此时终端当前目录为主目录):
javac a/b/Test.java
此时的class文件与源文件位于相同的目录,即/home/tarena/a/b/Test.class.
下面执行这个文件:
java a.b.Test
下面总结一下对于带包的类进行编译和执行时的一些要点:
1. 编译时,可以不考虑包结构的问题,不论用哪种方法,其实本质都是一样的,只需要让javac命令找到所需要编译的原文件即可.编译时可以用相对或者绝对路径来为javac命令提供源文件的位置信息.
2. 初学者易混淆classpath的作用,对于java命令的-cp选项和javac命令的-cp选项,以及配置环境变量时的CLASSPATH.其作用是不变的,都是指定所需要的class文件的位置.所不同的是,执行javac编译时的-cp选项用于指定被编译的源文件需要调用另外的用户自定义类的位置. 执行java命令是根据classpath来寻找所需要执行的class文件的位置.而javac命令不能根据classpath来找源文件,只能根据classpath来寻找所需要用到的类.
下面举例来说明该问题:
假设以下代码(该文件位置:/home/tarena/code/a/b/TA.java):
package a.b;
import c.d.TB;
public class TA
{
public static void main(String[]args)
{
System.out.println("Start to run****");
TB tb = new TB();
tb.show();
System.out.println("Stop to run****");
}
}
同时有另外一个文件(该文件位置:/home/tarena/code/tmp/c/d/TB.java):
package c.d;
public class TB
{
public void show()
{
System.out.println("Running!");
}
}
现在编译这个文件(此时终端当前目录为主目录):
javac -cp code/tmp code/a/b/TA.java
在编译过程中,编译器发现TA.java中需要用到TB类中的方法,于是在classpath范围中查找.也即在环境变量中设置的当前目录中以及编译时-cp选项指定的临时classpath路径中查找.现在编译器找到了TB.java,于是尝试编译它.然后使用编译好后的TB.class,如果没有TB.java而只有TB.class,则直接使用该class文件.
现在运行这个文件(此时终端当前目录为主目录):
java -cp code:code/tmp a.b.TA
这里用-cp指定了两个环境变量,因为TA.class和TB.class都不在classpath路径下,而且他们本身也不在同一目录下.
3. 执行class文件的时候,如果当前目录不是在包的上层目录,则要么使用cd命令切换至此,要么在执行java命令时使用-cp命令指定临时的classpath至此.不管怎样,java命令一定要在classpath中找到所需要的class文件.对于带包的class文件,classpath一定要指定到包的上层目录,而不是class文件的上层目录,此时应改把包结构也当作是class文件神圣不可分割的一部分.
以下面看这个程序为例(假设该文件的位置是/home/tarena/Test.Java):
package a.b;
public class Test
{
public static void main(String[]args)
{
System.out.println("This is a simple test!");
}
}
下面根据不同的编译方法来讨论:
第一种编译方法(此时终端当前目录为主目录):
javac Test.java
假设如果此时终端的当前目录是在/home,则编译命令则应改为:
javac /home/tarena/Test.java
或者使用相对路径:
javac tarena/Test.java
执行完该命令后,在/home/tarena/目录下生成一个Test.class文件.
如何运行这个文件?由于我们只能在包外运行class文件,所以首先要按照包的结构创建目录
mkdir -p a/b
mv Test.class a/b/
然后执行这个class文件(此时终端当前目录为主目录):
java a.b.Test
第二种编译方法(此时终端当前目录为主目录):
javac -d . Test.java
执行该命令后,编译器会根据包结构自动生成相应的目录,对于上面这个程序,则编译生成的class文件位于/home/tarena/a/b/Test.class.由于相应的目录也已经自动生成,并且当前目录恰是包结构的上层目录,所以此时直接执行该文件,不需要再像上面一样手动创建目录:
java a.b.Test
如果编译时-d的参数不是指定的当前目录,假设执行的命令如下(此时终端当前目录为主目录):
javac -d aaa/bbb Test.java
此时,class文件位于/home/tarena/aaa/bbb/a/b/Test.class.此时要执行该class文件有两种方法:
方法1(此时终端当前目录为主目录):
cd aaa/bbb
java a.b.Test
方法2(此时终端当前目录为主目录):
java -cp aaa/bbb a.b.Test
第三种编译方法:
先把源文件按照包结构放到指定的目录中,即首先执行如下命令(此时终端当前目录为主目录):
mkdir -p a/b
mv Test.java a/b/
然后执行如下命令编译这个文件(此时终端当前目录为主目录):
javac a/b/Test.java
此时的class文件与源文件位于相同的目录,即/home/tarena/a/b/Test.class.
下面执行这个文件:
java a.b.Test
下面总结一下对于带包的类进行编译和执行时的一些要点:
1. 编译时,可以不考虑包结构的问题,不论用哪种方法,其实本质都是一样的,只需要让javac命令找到所需要编译的原文件即可.编译时可以用相对或者绝对路径来为javac命令提供源文件的位置信息.
2. 初学者易混淆classpath的作用,对于java命令的-cp选项和javac命令的-cp选项,以及配置环境变量时的CLASSPATH.其作用是不变的,都是指定所需要的class文件的位置.所不同的是,执行javac编译时的-cp选项用于指定被编译的源文件需要调用另外的用户自定义类的位置. 执行java命令是根据classpath来寻找所需要执行的class文件的位置.而javac命令不能根据classpath来找源文件,只能根据classpath来寻找所需要用到的类.
下面举例来说明该问题:
假设以下代码(该文件位置:/home/tarena/code/a/b/TA.java):
package a.b;
import c.d.TB;
public class TA
{
public static void main(String[]args)
{
System.out.println("Start to run****");
TB tb = new TB();
tb.show();
System.out.println("Stop to run****");
}
}
同时有另外一个文件(该文件位置:/home/tarena/code/tmp/c/d/TB.java):
package c.d;
public class TB
{
public void show()
{
System.out.println("Running!");
}
}
现在编译这个文件(此时终端当前目录为主目录):
javac -cp code/tmp code/a/b/TA.java
在编译过程中,编译器发现TA.java中需要用到TB类中的方法,于是在classpath范围中查找.也即在环境变量中设置的当前目录中以及编译时-cp选项指定的临时classpath路径中查找.现在编译器找到了TB.java,于是尝试编译它.然后使用编译好后的TB.class,如果没有TB.java而只有TB.class,则直接使用该class文件.
现在运行这个文件(此时终端当前目录为主目录):
java -cp code:code/tmp a.b.TA
这里用-cp指定了两个环境变量,因为TA.class和TB.class都不在classpath路径下,而且他们本身也不在同一目录下.
3. 执行class文件的时候,如果当前目录不是在包的上层目录,则要么使用cd命令切换至此,要么在执行java命令时使用-cp命令指定临时的classpath至此.不管怎样,java命令一定要在classpath中找到所需要的class文件.对于带包的class文件,classpath一定要指定到包的上层目录,而不是class文件的上层目录,此时应改把包结构也当作是class文件神圣不可分割的一部分.