Java 版 (精华区)

发信人: DreamWeaver (enjoy java~), 信区: Java
标  题: Java从零开始 之 理解CLASSPATH
发信站: 哈工大紫丁香 (2003年05月28日08:05:49 星期三), 站内信件

/**
* Javor@Lilac
* 本篇旨在使用户能够理解CLASSPATH和环境变量里的CLASSPATH
* 创建日期:2003-05-27
* 最后修改日期:2003-05-27
* hdpan@hit.edu.cn
*/

    阅读本篇文章时,缺省的认为你是一个对Java有了初步了解或者是已经编写
一个HelloWorld程序的新手。

    如果你已经按照上篇理解了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 net.eastdawn.util.*;

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

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

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

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

D:.
+---Classes
|   +---Acme
|   |   \---JPM
|   |       \---Encoders
|   +---net
|       +---eastdawn
|           +---jdbc
|           +---util
+---JavaTest
    +---HelloWorld.java    
    |
    +---net
         +---eastdawn
             +---test
             +---swing


        首先找到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、.....

[完]
※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 202.118.239.37]
--
--
※ 修改:·DreamWeaver 於 05月28日08:08:51  修改本文·[FROM: 202.118.239.4]
※ 转载:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: 202.118.239.4]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:3.974毫秒