概要
Classpath和Codebase是Java中非常重要的两个概念初学者如果没有掌握这两个概念在遇到诸如ClassNotFoundException或者相关的异常时不知所措另外很多其它方面的错误往往也和Classpath有关本文将详细解释这两个概念并且描述在命令行方式和集成开发环境(以JBuilder为例)中的设置方式
什么是Classpath
Classpath是Java中的重要概念它描述了Java虚拟机在运行一个Class时在哪些路径中加载要运行的类以及运行的类要用到的类简单的说就是像操作系统的path只不过这个classpath是由Java的虚拟机来使用查找需要加载的类而操作系统的path是由操作系统用来查找用户输入的可执行程序同path一样classpath也是一个环境变量可以通过set命令来设置
Classpath和Java包的关系
Java的包(Package)和classpath关系密切包是以分割的SUN建议使用域名的逆向排列来区分不同的包以避免沖突如panyutil在一个包里的类在存储的时候需要存储在和包名相同的目录里如上述panyutil包中的Sampleclass要存储在com\company\util目录中
Classpath有两种表达方式一种是指向目录的classpath如C:\work\classes表示C:\work\classes目录是一个classpath条目另一种方式是指向压缩文件的classpath如C:\work\utiljar表示C:\work\utiljar文件是一个classpath条目任何一个包含Java类的zip格式的压缩文件都可以作为classpath的条目
那么classpath和包到底是什么关系呢?简单的说就是Java虚拟机在加载类的时候以这样一种方式查找具体的类文件classpath+包存储的目录+具体的类文件如classpath中有一个c:\work\classes条目需要加载的类是panyutilSampleclass那么在加载这个类的时候虚拟机会查找c:\work\classes\com\company\util目录如果Sampleclass在这个目录中虚拟机就可以找到如果这个类不在这个目录中同时也不在任何一个其它classpath中那么虚拟机会抛出一个ClassNotFoundException
Classpath的顺序和类版本沖突
Java虚拟机在加载类的时候查找classpath是有顺序的如果在classpath中有多个条目都有同一个名称的类那么在较前位置的类会被加载后面的会被忽略这种按照顺序的类加载可能会导致类的版本沖突例如classpath=c:\servlet\servletjarc:\servlet\servletjar那么在实际应用的过程中你使用的是servlet而不是servlet很多时候如果不注意这一点可能会导致奇怪的异常
命令行状态下的classpath设置
命令行状态下的classpath可以通过两种方式设置
一种是直接设置环境变量例如在windows环境下我们使用set命令
set classpath=c:\work\classesc:\work\utiljar
另一种方式是在执行javacjava或者其它Java命令时直接指定classpath
java classpath c:\work\classes;c:\work\utiljar panyutilSample
集成开发环境下的classpath设置
集成开发环境中设置classpath一般通过其用户界面进行各种集成开发环境的classpath设置各不相同我们以JBuilder为例来说明集成开发环境下的classpath
设置Jbuilder的Library
JBuilder中的classpath要通过类库来设置首先选择Tools>Configure Library然后点击New按钮点击Add可以选择要增加的类库这个类库可以是目录也可以是zip格式的压缩文件如jar或者zip
设置项目需要用到的Library
在设置了类库之后在JBuilder中运行一个class时并不会马上查找你加入的类库而是要在Project>Project Properties>Path>Required Library中设置选择Add按钮你就可以增加自己的classpath条目了
什么是Codebase
使用Java语言编写的程序不仅可以在本地的classpath中加载类也可以根据需要从网络上下载类为了使Java程序可以从网络上下载类我们需要使用codebasecodebase指定了Java程序在网络上何处可以找到需要的类
在Java Applet中使用codebase
众所周知可以在Java Applet中使用codebase指定Applet加载其所需要的类的网络位置例如
代码
这个Applet指定了其所用的类可以在服务器上Applet所在的目录下找到
在Java Application中使用codebase
不仅在Applet中可以使用codebase在Application中也可以使用codebase这样Application除了可以使用classpath中的类还可以使用网络上的类例如
java -classpath c:\work\classes -codebase Sample
应用程序Sample不仅可以使用c:\work\classes中的类还可以使用中的类
Classpath和codebase的关系
既然Java虚拟机即可以在classpath中加载类又可以在codebase中加载类那么classpath和codebase是什么关系呢?实际上Classpath和codebase都是由系统类加载器(Class Loader)使用的类加载器在加载一个类的时候首先在classpath中查找需要的类然后在codebase中查找第一个被查找到的类会被加载例如在早期的JDK版本中缺省codebase是空值如果没有在classpath中指定(当前目录)运行当前目录下的java class时会出现ClassNotFoundException而在晚些版本中缺省codebase是所以即使不在classpath中加入当前目录下的java class仍然可以正常运行
总结
初学Java的朋友一定要掌握classpath和codebase的概念理解其内涵如果出现编译运行程序的过程中出现什么问题首先应该考虑是否是classpath的问题实际上甚至一些非常复杂的应用中比如服务器端应用都会因为classpath的设置而出现莫名其妙的问题如果大家在阅读本文的过程中有什么问题请提出来大家一起讨论