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,这是笔者不推荐的。推荐的几种做法是

  1. 在命令行中用-classpath或-cp选项
  2. 在命令行中设置classpath环境变量
  3. 编写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选项的时候,才会把当前目录加入到类路径中。

《Java从入门到失业》第四章:类和对象(4.6):类路径的更多相关文章

  1. 《Java从入门到失业》第二章:Java环境(四):IDE集成环境

    2.4IDE集成环境 在掌握了编写.编译和运行Java程序的基本步骤以后,你肯定就在想,这太麻烦了,有没有更好的工具?当然有了,那就是IDE.IDE就是专业的集成开发环境(Integrated Dev ...

  2. 《Java从入门到失业》第一章:计算机基础知识(一):二进制和十六进制

    0 前言 最近7年来的高强度工作和不规律的饮食作息,压得我有些喘不过气,身体也陆续报警.2018年下半年的一场病,让我意识到了这个问题的严重性,于是开始强制自己有规律饮食和作息,并辅以健身锻炼,不到2 ...

  3. 《Java从入门到失业》第二章:Java环境(一):Java SE安装

    从这一章开始,终于我们可以开始正式进入Java世界了.前面我们提到过,Java分三个版本,我们这里只讨论Java SE. 2.1Java SE安装 所谓工欲善其事,必先利其器.第一步,我们当然是要下载 ...

  4. 《Java从入门到失业》第一章:计算机基础知识(三):程序语言简介

    1.3程序语言简介 我们经常会听到一些名词:低级语言.高级语言.编译型.解释型.面向过程.面向对象等.这些到底是啥意思呢?在正式进入Java世界前,笔者也尝试简单的聊一聊这块东西. 1.3.1低级语言 ...

  5. 《Java从入门到失业》第二章:Java环境(三):Java命令行工具

    2.3Java命令行工具 2.3.1编译运行 到了这里,是不是开始膨胀了,想写一段代码来秀一下?好吧,满足你!国际惯例,我们写一段HelloWorld.我们在某个目录下记事本,编写一段代码如下: 保存 ...

  6. 《Java从入门到失业》第二章:Java环境(二):JDK、JRE、JVM

    2.2JDK.JRE.JVM 在JDK的安装目录中,我们发现有一个目录jre(其实如果是下一步下一步安装的,在和JDK安装目录同级目录下,还会有一个jre目录).初学Java的同学,有时候搞不清楚这3 ...

  7. 《Java从入门到失业》第一章:计算机基础知识(二):计算机组成及基本原理

    1.2计算机组成及基本原理 1.2.1硬件组成 这里说的计算机主要指微型计算机,俗称电脑.一般我们见到的有台式机.笔记本等,另外智能手机.平板也算.有了一台计算机,我们就能做很多事情了,比如我在写这篇 ...

  8. 《Java从入门到失业》第四章:类和对象(4.5):包

    4.5包 前面我们已经听过包(package)这个概念了,比如String类在java.lang包下,Arrays类在java.util包下.那么为什么要引入包的概念呢?我们思考一个问题:java类库 ...

  9. #Python编程从入门到实践#第四章笔记

    #Python编程从入门到实践#第四章笔记   操作列表 ​​​1.遍历列表 使用for循环,遍历values列表 for value in values: print(value) 2.数字列表 使 ...

  10. ArcGIS for Desktop入门教程_第四章_入门案例分析 - ArcGIS知乎-新一代ArcGIS问答社区

    原文:ArcGIS for Desktop入门教程_第四章_入门案例分析 - ArcGIS知乎-新一代ArcGIS问答社区 1 入门案例分析 在第一章里,我们已经对ArcGIS系列软件的体系结构有了一 ...

随机推荐

  1. 内存不够用还要速度快,终于找到可以基于 File 的 Cache 了

    一:背景 1. 讲故事 18年的时候在做纯内存项目的过程中遇到了这么一个问题,因为一些核心数据都是飘在内存中,所以内存空间对我们来说额外宝贵,但偏偏项目中有些数据需要缓存,比如说需要下钻的报表上的点, ...

  2. Flink-1.10.0中的readTextFile解读

    Flink-1.10.0中的readTextFile解读 最近在学习Flink,研究了一些东西,在准备自定义一个简单的监听文件的source作为练手的时候,遇到了一个问题.就是应该如何在自己的sour ...

  3. Flink-1.10中的StreamingFileSink相关特性

    一切新知识的学习,都离不开官网得相关阅读,那么StreamingFileSink的官网介绍呢? https://ci.apache.org/projects/flink/flink-docs-rele ...

  4. 黑马新版PYTHON教学课程(全)资料加视频完整版百度网盘资料

    黑马新版PYTHON教学课程(全)资料加视频完整版 无加密,适合0基础人群.基础班+就业班.不用解压在线看 百度网盘地址一 淘宝店地址二

  5. (新手向)N皇后问题详解(DFS算法)

    非常经典的一道题: N皇后问题: 国际象棋中皇后的势力范围覆盖其所在的行.列以及两条对角线,现在考察如下问题:如何在n x n的棋盘上放置n个皇后,使得她们彼此互不攻击 . 免去麻烦我们这里假定n不是 ...

  6. [状压DP]P1441 题解 砝码称重

    前置知识:状压DP 洛谷传送门 emm....看到题目,我第一个想到的就是枚举.暴力大法好! 具体怎么枚举?当然是子集枚举啦!枚举出每一个可能的砝码选择方案.对于每一个合法的(也就是选取数量等于\(n ...

  7. Istio的流量管理(实操三)

    Istio的流量管理(实操三) 涵盖官方文档Traffic Management章节中的egress部分.其中有一小部分问题(已在下文标注)待官方解决. 目录 Istio的流量管理(实操三) 访问外部 ...

  8. graph attention network(ICLR2018)官方代码详解(te4nsorflow)

    论文地址:https://arxiv.org/abs/1710.10903 代码地址: https://github.com/Diego999/pyGAT 我并没有完整看过这篇论文,但是在大致了解其原 ...

  9. 截图还在使用QQ的Ctrl + Alt + A 截图?还不会网页长截图?

    截图还在使用QQ的Ctrl + Alt + A 截图?还不会网页长截图?   手机自带快捷键,常常使用组合键进行快速截图编辑发好友.保存等,但是貌似到了电脑截图就出现了一大堆拍屏幕党,不少人需要打开微 ...

  10. Python学习—Anaconda详细 下载、安装与使用,以及如何创建虚拟环境,不仅仅只有安装步骤哦

    上一期我们介绍了Python.Pycharm.Anaconda三者之间的关系以及使用,这一期主要详细介绍如何在Windows上下载和安装工具Anaconda,然后使用其自带的conda管理不同项目的虚 ...