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. elementUI table怎么实现点击上移下移

    其实炒鸡简单...   <el-table :data='tableData' > ... ...  <el-table-column label="操作" al ...

  2. 极简 Node.js 入门 - 3.5 文件夹操作

    极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...

  3. 前端用vue怎么接收并导出文件

    window.location.href = "excel地址" 如果是 get 请求,那直接换成 window.open(url) 就行了 创建一个隐藏的 iframe,把 if ...

  4. 【Android】SlidingTabLayout实现标题栏,教你制作title标题 简单易学。

    SlidingTabLayout 作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985, QQ986945193 微博:http://weibo.com/m ...

  5. Vue.use() 不一样的发现

    1.Vue.use()首先是可以接受一个函数 var a = function () { console.log(a)}Vue.use(a) // 没有问题会输出a 2.当这个a上面有install属 ...

  6. 什么是Nginx -九五小庞

  7. 轻轻松松学CSS:媒体查询

    轻轻松松学CSS:利用媒体查询创建响应式布局 媒体查询,针对不同的媒体类型定制不同的样式规则.在网站开发中,可以创建响应式布局. 一.初步认识媒体查询在响应式布局中的应用 下面实例在屏幕可视窗口尺寸大 ...

  8. OpenResty 作者章亦春访谈实录

    [软件简介] OpenResty (也称为 ngx_openresty)是一个全功能的 Web 应用服务器.它打包了标准的 Nginx 核心,很多的常用的第三方模块,以及它们的大多数依赖项. 通过众多 ...

  9. 11 vue 自定义全局方法

    //global.js// 定义vue 全局方   // 定义vue 全局方法 建议自定义的全局方法加_ 以示区分 export default {   install(Vue, options =  ...

  10. 转载:Oracle常见字段类型

    转载节选自:https://bbs.csdn.net/topics/220059184 数据类型 参数 描述 char(n) n=1 to 2000字节 定长字符串,n字节长,如果不指定长度,缺省为1 ...