《Java从入门到失业》第四章:类和对象(4.6):类路径 | 您所在的位置:网站首页 › 完整路径描述是什么意思 › 《Java从入门到失业》第四章:类和对象(4.6):类路径 |
4.6类路径
4.6.1什么是类路径
前面我们讨论过包,知道字节码文件最终都会被放到和包名相匹配的树状结构子目录中。例如上一节的例子:
其实类还有一种存放方式,就是可以归档到一个jar文件中,jar文件其实就是把字节码文件连同子目录一同归档到一个压缩文件中。jar文件是使用zip格式压缩的,我们可以使用zip程序来查看和解压jar文件。其实Java自带的类库就是jar文件。例如JRE安装目录jre/lib和jre/lib/ext下就有很多jar。我们看一下jre/lib/rt.jar的结构:
我们看到,无论是单独存放还是归档jar,都有一个基目录(黑色部分),上面2个图的基目录分别为: D:\Java大失叔\workspace\BaseJava\bin C:\Program Files\Java\jre1.8.0_261\lib 我们采用基目录+包树状结构,就可以定位到某个类,例如: D:\Java大失叔\workspace\BaseJava\bin\com\javadss\javase\ch04\PackageTest.class C:\Program Files\Java\jre1.8.0_261\lib\java\lang\System.class 这里的基目录,就是类路径,英文叫classpath。类路径就是java编译器或JVM用来定位类的基目录,类路径可以有多个,是一组路径的集合。无论是编译还是运行,都需要设置类路径,类路径的形式和操作系统相关。 在Windows环境下,采用分号(;)分隔,如果路径中含有空格,需要用引号(“”)括起来,形式如下: D:\Java大失叔\workspace\BaseJava\bin; “C:\Program Files\Java\jre1.8.0_261\lib”; 在Linux环境下,采用冒号(:)分隔,形式如下: usr/local/bin:usr/dss/java/bin 4.6.2编译我们假设有3个类:A、B、C。main方法在C中,C中访问了A和B,同时还访问了java.lang.System类。它们的结构如下:
其中A和B是空类,C类的代码如下: package com.javadss.javase.ch04.ccc; import com.javadss.javase.ch04.aaa.A; import com.javadss.javase.ch04.bbb.B; public class C { public static void main(String[] args) { A a = new A(); B b = new B(); System.out.println("classpath"); } }现在我们用命令行来编译A、B、C,还记得编译命令吗?编译命令如下: javac -d 编译后class的路径 源文件 则编译命令如下: javac -d D:\Java大失叔\workspace\BaseJava\bin D:\Java大失叔\workspace\BaseJava\src\com\javadss\javase\ch04\aaa\A.java javac -d D:\Java大失叔\workspace\BaseJava\bin D:\Java大失叔\workspace\BaseJava\src\com\javadss\javase\ch04\bbb\B.java javac -d D:\Java大失叔\workspace\BaseJava\bin D:\Java大失叔\workspace\BaseJava\src\com\javadss\javase\ch04\ccc\C.java 编译A、B的时候没有问题,但是编译C的时候,遇到了问题,报错:
这是因为C类中引用了A和B,但是编译命令中没有指定A和B的绝对路径,因此会报错“程序包不存在”、“找不到符号”这些错误。我们可以在命令行中增加-classpath或-cp选项,设置A和B的类路径,设置后的命令如下: javac -cp D:\Java大失叔\workspace\BaseJava\bin -d D:\Java大失叔\workspace\BaseJava\bin D:\Java大失叔\workspace\BaseJava\src\com\javadss\javase\ch04\ccc\C.java 再次执行,编译成功。有的同学可能要问了,C中也引用了java.lang.System类,为什么不用设置System类的类路径呢?这是因为System属于JDK的类库,javac编译时,会默认搜寻JDK的类路径。 当我们的程序引用了很多类,这些类分散在不同的地方,就需要把所有的类路径都写到命令行中,比如类路径为: D:\Java大失叔\workspace\BaseJava\bin;.;“C:\Program Files\Java\jre1.8.0_261\lib”; 注意,中间有一个“.”,这个表示当前目录。当我们这样写的时候会导致命令行非常长,我们可以用设置环境变量classpath的方式来减少命令行的长度,设置环境变量的具体形式和操作系统有关,Windows命令格式如下: set classpath=类路径集合 例如: set classpath= D:\Java大失叔\workspace\BaseJava\bin; “C:\Program Files\Java\jre1.8.0_261\lib”; 我们在命令行窗口中执行上述命令后,在窗口关闭之前,所有的编译命令都不需要用-cp选项来设置类路径了。网上有很多网文或教程中,都喜欢在系统环境变量中设置classpath,这是笔者不推荐的。推荐的几种做法是 在命令行中用-classpath或-cp选项 在命令行中设置classpath环境变量 编写shell脚本,将设置classpath环境变量和编译命令一起写入脚本事实上,编译器会按照下面方式搜寻类: 从JDK的类库中搜寻 从当前目录下搜寻 从classpath环境变量中搜寻 从classpath选项中搜寻如果搜寻类的时候发现了一个以上的同一个类,就会产生编译错误。 另外,编译器还会做很多其他工作,例如编译器在搜寻类的时候,还会查看源文件,如果发现被引用的类的源文件比类文件新,还会自动的重新编译源文件。 4.6.3运行用命令行运行程序和编译类似,我们也需要用-classpath或-cp选项指定类路径,常用的命令格式为: java -classpath 类路径 包含main方法的类的完整类名 我们来运行上面的例子C类,则命令行如下: javac -cp D:\Java大失叔\workspace\BaseJava\bin com.javadss.javase.ch04.ccc.C 同样,对于JDK的核心类库,我们不需要显示的加到类路径中。当然,我们也可以用设置classpath环境变量的方法预先设置,然后执行运行命令的时候可以不用加上-classpath选项了。 这里需要注意一点,对于编译器来说,总是会搜寻当前目录(换句话说,会默认把当前目录加入到类路径),但是虚拟机JVM仅仅在不设置classpath环境变量,也不加-classpath或-cp选项的时候,才会把当前目录加入到类路径中。
我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2ayar2hbe7i8s |
CopyRight 2018-2019 实验室设备网 版权所有 |