《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选项的时候,才会把当前目录加入到类路径中。
《Java从入门到失业》第四章:类和对象(4.6):类路径的更多相关文章
- 《Java从入门到失业》第二章:Java环境(四):IDE集成环境
2.4IDE集成环境 在掌握了编写.编译和运行Java程序的基本步骤以后,你肯定就在想,这太麻烦了,有没有更好的工具?当然有了,那就是IDE.IDE就是专业的集成开发环境(Integrated Dev ...
- 《Java从入门到失业》第一章:计算机基础知识(一):二进制和十六进制
0 前言 最近7年来的高强度工作和不规律的饮食作息,压得我有些喘不过气,身体也陆续报警.2018年下半年的一场病,让我意识到了这个问题的严重性,于是开始强制自己有规律饮食和作息,并辅以健身锻炼,不到2 ...
- 《Java从入门到失业》第二章:Java环境(一):Java SE安装
从这一章开始,终于我们可以开始正式进入Java世界了.前面我们提到过,Java分三个版本,我们这里只讨论Java SE. 2.1Java SE安装 所谓工欲善其事,必先利其器.第一步,我们当然是要下载 ...
- 《Java从入门到失业》第一章:计算机基础知识(三):程序语言简介
1.3程序语言简介 我们经常会听到一些名词:低级语言.高级语言.编译型.解释型.面向过程.面向对象等.这些到底是啥意思呢?在正式进入Java世界前,笔者也尝试简单的聊一聊这块东西. 1.3.1低级语言 ...
- 《Java从入门到失业》第二章:Java环境(三):Java命令行工具
2.3Java命令行工具 2.3.1编译运行 到了这里,是不是开始膨胀了,想写一段代码来秀一下?好吧,满足你!国际惯例,我们写一段HelloWorld.我们在某个目录下记事本,编写一段代码如下: 保存 ...
- 《Java从入门到失业》第二章:Java环境(二):JDK、JRE、JVM
2.2JDK.JRE.JVM 在JDK的安装目录中,我们发现有一个目录jre(其实如果是下一步下一步安装的,在和JDK安装目录同级目录下,还会有一个jre目录).初学Java的同学,有时候搞不清楚这3 ...
- 《Java从入门到失业》第一章:计算机基础知识(二):计算机组成及基本原理
1.2计算机组成及基本原理 1.2.1硬件组成 这里说的计算机主要指微型计算机,俗称电脑.一般我们见到的有台式机.笔记本等,另外智能手机.平板也算.有了一台计算机,我们就能做很多事情了,比如我在写这篇 ...
- 《Java从入门到失业》第四章:类和对象(4.5):包
4.5包 前面我们已经听过包(package)这个概念了,比如String类在java.lang包下,Arrays类在java.util包下.那么为什么要引入包的概念呢?我们思考一个问题:java类库 ...
- #Python编程从入门到实践#第四章笔记
#Python编程从入门到实践#第四章笔记 操作列表 1.遍历列表 使用for循环,遍历values列表 for value in values: print(value) 2.数字列表 使 ...
- ArcGIS for Desktop入门教程_第四章_入门案例分析 - ArcGIS知乎-新一代ArcGIS问答社区
原文:ArcGIS for Desktop入门教程_第四章_入门案例分析 - ArcGIS知乎-新一代ArcGIS问答社区 1 入门案例分析 在第一章里,我们已经对ArcGIS系列软件的体系结构有了一 ...
随机推荐
- 提升布局能力!理解 CSS 的多种背景及使用场景和技巧
CSS background是最常用的CSS属性之一.然而,并不是所有开发人员都知道使用多种背景.这段时间都在关注使用多种背景场景.在本文中,会详细介绍background-image`属性,并结合图 ...
- CSS动画实例:行星和卫星
设页面中有<div class=" planet "></div>,用来绘制一个行星和卫星图形.这个图形包括三部分:行星.卫星和卫星旋转的轨道.定义. pl ...
- Reinforcement learning in artificial and biological systems
郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! Abstract 在生物和人工系统的学习研究之间,已经有富有成果的概念和想法流.Bush and Mosteller,Rescorla a ...
- elementUI的隐藏组件el-scroll--滚动条
由于原生的滚动条存在兼容性问题并且样式不是太美观,在项目中经常使用的是elementui,发现elementui中有个隐藏的组件,就是element官网使用的滚动条,可以优化滚动条样式.鼠标经过的时候 ...
- 如何解决 iframe 无法触发 clickOutside
注:(1)非原创,来自https://blog.csdn.net/weixin_33985679/article/details/89699215.https://zhuanlan.zhihu.com ...
- python 四位玫瑰数 + 100以内素数求和
四位玫瑰数 描述 ...
- 用Java写编译器(1)- 词法和语法分析
词法和语法分析器构建 ANTLR简介 ANTLR全称ANother Tool for Languate Recognition,是基于LL(*)算法实现的语法分析器生成器和词法分析器生成器,由旧金山大 ...
- if-else 可以这么写
最近部门在对以往的代码做一些优化,我在代码中看到一连串的 if(){}elseif(){} 的逻辑判断.这明显是有优化空间的. 由于内部代码不适合分享,这里我就用 <输出今天为星期几> 来 ...
- Android中_TextView属性的XML详解 包括单行显示等等。
<pre name="code" class="html">属性名称 描述 android:autoLink 设置是否当文本为URL链接/email ...
- 盒子上下滚动到js 底部触发的事件
//html是用法举列子,js亲测有效(把这段js#scro加到你要滚动的盒子) <div id="scro"> <div>1</div> & ...