深入理解PATH CLASSPATH

来源:互联网 发布:java while 两个条件 编辑:程序博客网 时间:2024/06/05 17:37

转帖:http://tieba.baidu.com/f?kz=293706722

 

认识PATH

如果你使用过 DOS或者 Linux这样的字符界面的操作系统,相信你对PATH已 经有了一定的了解。而现在的朋友们几乎连 DOS都没有用过,都是在MS的图形窗 口下长大的,对PATH的认识远没有当年苦背 DOS命令的一代深刻了。

PATH,也就是路径。我们所使用的操作系统一般都是树形目录结构,例如我 正在使用的WinXP系统,在系统的最上级目录有C:,D:,E: 目录,在C:下又有许 多目录和文件:

可以看出是树形结构了吧?:), 当我们描述一个文件的位置时,就要用到路径了。比如,Windows目录在哪里?你会很快的说:C:/Windows/,那notepad.exe 文件在哪里?你找了一会儿回答说:C:/WINDOWS/notepad.exe。right! 这些就 是路径。

路径是指从树型目录中的某个目录层次到某个文件的一条道路。和物理上的 路径是一样的,如同你从实验室回到寝室的路,就是一条路径,顺着路径,你可 以找到你要找到的东西,当然,这个东西一定要在路径上。

在对文件进行访问时,要给出文件所在的路径。 路径又分相对路径和绝对路 径。 绝对路径是指从"根"开始的路径;相对路径是从用户工作目录开始的路径。

比如你现在在A楼工作,有人问你厕所在哪里?你说:隔壁。
这个隔壁就是相对路径,是相对于你现在所在的位置所说

如果别人要问你: 你家是哪里的?你会说,内蒙古赤峰阿旗。
这里的内蒙古赤峰阿旗就是绝对位置。 当然,这时默认的根是中国,否则就说:..... 银河系太阳系地球..... :)

现在你应该知道什么是PATH也就是路径了吧?

接下来,说一说系统的环境变量里面的PATH是干什么用的。

按照上节所述的方法查看环境变量(提示一下,Win98系统看C:/autoexec.bat WinNT、Win2K、WinXP系统:控制面板-〉系统-〉高级-〉环境变量,Linux系统为 /etc/profile),你会发现有一个名为PATH的东西,他的值为:


%SystemRoot%/system32;%SystemRoot%;%SystemRoot%/System32/Wbem


注意:不可能完全一样,但是可能完全不一样,相信自己,你找对了,这就是PATH。

这个PATH是干什么用的呢?例如,我经常使用C:/Windows/notepad.exe这个文件。如果在命令行模式下(因为在命令行下你猜可以看得到,如果用鼠标,你根本看不到调用了哪些东西),现在我在D:/,我想用notepad.exe打开D:/a.txt 那么,我要使用和命令:


D:/>C:/Windows/notepad.exe a.txt 


如果频繁的使用这个notepad.exe,我一直都要敲入C:/Windows/notepad.exe 再加上我的打字速度不快,还一直担心打太多的字会损害指关节,于是我决定偷懒。我将上面的PATH改为:

%SystemRoot%/system32;%SystemRoot%;%SystemRoot%/System32/Wbem;C:/Windows/ 

注意我后面加的东西,这样我就可以这样来使用D:/>C:/Windows/notepad.exe了

D:/>notepad.exe a.txt 


是不是很方便呀?如果C:/Windows/notepad.exe的路径更长,偷懒的效果就 更明显了!:)。

当我们敲入notepad.exe的时候,系统首先在当前目录寻找notepad.exe,结 果没找到,于是在系统的环境变量PATH里面寻找:
%SystemRoot%/system32/notepad.exe 没找到
%SystemRoot%/notepad.exe 没找到
%SystemRoot%/System32/Wbem/notepad.exe 没找到
C:/Windows/notepad.exe 找到啦~,于是调用此文件~!

现在明白环境变量PATH的作用了吧?:)

如果你已经按照上篇理解了PATH,那么接下来对 CLASSPATH的理解就顺理成 章了。

因为我们可爱的Java要实现跨平台,而每个平台的文件的路径的表示方法是 不一样的,所以呢,Java就不能使用具体的操作系统提供的PATH了,可是Java还要需要调用不同的文件 (这里所说的文件是Java的文件,在写Java程序的时候, 我们不能把所有的代码写到一个文件里吧?),那怎么办呢?

于是,有人想出办法,每个系统不是有PATH来提供文件的检索吗?我们的jvm (还知道jvm是什么吗?如果忘记了,看前面) 不就是一个逻辑意义上的平台吗? 那么,我们就可以定义另外一种路径来提供文件的检索呀?于是 CLASSPATH就诞生了!因为所有的Java文件到头来都是CLASS文件(都是*.class),所以这个PATH 就是CLASS的PATH,也就是CLASSPATH啦~。

 

说到这里,你应该明白原来 CLASSPATH像系统里面的PATH一样,都是一种路 径系统里的PATH的路径是提供系统里面文件的检索, CLASSPATH是在Java虚拟机 工作的时候提供对CLASS的检索。

既然已经决定创造出一个CLASSPATH出来,那么该怎么实现这个CLASSPATH呢?当然还是不能脱离具体的操作系统,巧妇难为无米之炊,我们建不出空中楼阁。 PATH挺像我们需要的 CLASSPATH的,那么我们就把PATH加工一下或者改造一下, 当作我们需要的东西来用吧。事实上也是这么做的。

于是我们在系统的环境变量里面添加一个新的变量叫 CLASSPATH。他的描述方法用PATH的描述方法:

.;D:/classes/;D:/j2sdk1.4.2b/lib/dt.jar;D:/j2sdk1.4.2b/lib/tools.jar 


可以看到,新的变量 CLASSPATH使用的系统的路径表示的(例如D:/classes/ 就是一个系统的路径),但是不能用环境环境变量PATH,所以不能写成:

%Path%;D:/classes/;D:/j2sdk1.4.2b/lib/dt.jar;D:/j2sdk1.4.2b/lib/tools.jar 

或者

$Path;D:/classes/;D:/j2sdk1.4.2b/lib/dt.jar;D:/j2sdk1.4.2b/lib/tools.jar  

这样当jvm想要调用Java文件(class文件)的时候,不能通过PATH寻找,只能 从CLASSPATH寻找了。

让我们看一个例子:

D:/JavaTest>javac HelloWorld.java  


这一步的执行过程是:

1.系统发现启动的程序是javac,于是开始寻找javac.exe。 寻找的次序按照上篇所述寻找notepad.exe的顺序雷同

2.找到之后,运行javac.exe,附加参数HelloWorld.java

3.javac编译HelloWorld.java -> HelloWorld.class
如果HelloWorld.java中有其他类库(类库就是分类整理好的一堆class 文件)的引用,例如:

import java.io.*; 
import com.hdpan.util.*; 

对于标准类库的引用,像上面的"java.io.*",可以直接使用,也就是说它 不需要显示的放在系统的环境变量CLASSPATH中。

而对于非标准类库,像"com.hdpan.util.*",javac怎么来找到它呢? 上面说了,它是通过系统的环境变量CLASSPATH来找:让我们再回顾一下我 们的CLASSPATH是如何设定的:

.;D:/classes/;D:/j2sdk1.4.2b/lib/dt.jar;D:/j2sdk1.4.2b/lib/tools.jar 

然后再看看当前的目录结构:

首先找到D:/JavaTest/HelloWorld.java,这个是我们正在编译的文件,接 下来,我们来看看javac是怎么来寻找net.eastdawn.util.*的:

发现是非标准类库,开始搜索CLASSPATH,第一个CLASSPATH是".",也就是当前目录,当前目录有一个net文件夹,然后eastdawn,可是eastdawn文件夹下面没有util文件夹,于是第一个CLASSPATH搜索失败。然后搜索第二个CLASSPATH "D:/classes/",果然再此发现了net/eastdawn/util/,于是这里编译通过。

至此,D:/JavaTest>javac HelloWorld.java 执行完毕。

现在也应该明白为什么在CLASSPATH的前面会有一个 "."了吧?他就是为了优先 搜索当前目录下的class。

运行完javac之后,当前目录多一个文件:HelloWorld.class,运行它:

D:/JavaTest>java HelloWorld  

(注意:是java HelloWorld,而不是java HelloWorld.class)

这里用到了java命令,所以启动一个jvm(jvm是什么?看前面的文章吧,:)), 开始搜索CLASSPATH,首先按照"."搜索,在当前目录找到了HelloWorld.class, 于是运行!

现在你明白了为什么许多人别写了HelloWorld却在运行的时候出现这个了吧:


Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld  

你想对了,就是因为jre不能根据CLASSPATH来找到HelloWorld.class,哪怕HelloWorld.class就在当前目录,当时环境变量的CLASSPATH里没有 "."这个设定,同样是找不到!哈哈,java怎么这么笨啊~,是很笨的,那么,聪明的我们 就不要再犯这样的错误喽~。
然后呢,一大堆的问题你都应该可以解决了,比如频繁出现的
NoClassDefFoundError、class not found、.....