http://www.cnblogs.com/wxf0701/archive/2008/08/23/1274579.html

1.class搜索路径的重要性 
     理解class搜索路径对所有Java开发人员来说都很重要,但是,IDE的广泛使用掩盖了这项技术,使大家普遍对它缺乏了解,甚至包括好多老鸟。这个问题在开发分布式应用时尤其严重,因为应用程序运行时的系统环境可能和开发时的大不相同。 
     本文详细描述了某些Java类被其他代码引用时,Java编译器和JVM如何使用类搜索路径定位这些类。这儿用一个非常简单的例子——同一个包 中的两个类——来具体说明。我们将通过不同的方式来编译这两个类,根据classpath的设置不同,编译可能成功也可能失败。 
     为了最清楚的说明这个问题,我们将只使用命令行工具进行编译。交互式开发工具有它们自己操作classpath的方法,这些方法因产品而异。 
     至于是由Java编译器在编译时定位需要的类,还是由JVM在运行时来做,这两种方法没有本质的区别。但编译器可以从源代码中编译需要的类,而JVM不行。下面的例子中我们用编译器来做,但在运行时的实现也完全类似。
2.实例
     本例有两个很小的类:com.web_tomorrow.CPTest1 和 com.web_tomorrow.CPTest2,如下所示:

     package com.web_tomorrow;

     public class CPTest1 {

public static void main(String[] args) {

System.out.println ("Run CPTest1.main()");

}

}

     package com.web_tomorrow;

     public class CPTest2 {

          public static void main(String[] args) {

System.out.println ("Run CPTest2.main()");

CPTest1 cpt1 = new CPTest1();

}

}

Java代码组织的一个最基本规则就是`package name = directory name'(“包名 = 目录名”)。我们将为这两个类建立对应的目录结构,它们在包com.web_tomorrow中,所以我们创建目录 com/web_tomorrow来存放源代码:

[root] com 
     web_tomorrow 
     CPTest1.java 
     CPTest2.java 
     在本文中我用符号`[root]'来表示存放上述结构的任意目录,也就是说,根目录的位置由你决定。当然这会随安装这些文件的方式不同而不一样。
3.基本原理 
     让我们来尝试用命令行工具javac来编译CPTest1.java。为了完全禁止类搜索路径(以防已有的设置影响本例),我们在javac上加上选项`-classpath ""'。 
     作为第一次试验,我们先换到CPTest1.java所在的目录下,并且尝试用javac和文件名进行编译。 
     cd [root]/com/web_tomorrow 
     javac -classpath "" CPTest1.java 
     操作成功,因为编译器能发现CPTest1.java (它就在当前的工作目录下),并且CPTest1没有引用任何其他类。输出文件CPTest1.class在CPTest1.java的相同目录下,因为 你没有给编译器任何信息让它作其它处理。到现在为止,一直都很好。现在让我们用同样的方式来试一下CPTest2。仍然在web_tomorrow目录 下,执行命令: 
     javac -classpath "" CPTest2.java 
     虽然目录还是刚才的目录,CPTest1和CPTest2也在相同的包里,这一次却失败了。
     错误信息可能是这样的: 
     CPTest2.java:7: cannot resolve symbol 
     symbol : class CPTest1 
     location: class com.web_tomorrow.CPTest2 
     CPTest1 cpt1 = new CPTest1(); ^ 
     这一次和上一次成功的情况之间的区别之一就是CPTest2中有对CPTest1的引用: 
     CPTest1 cpt1 = new CPTest1(); 
     这次发生了什么呢?当编译器遇到对CP1Test的引用时,它会认为CP1Test类与当前编译的CP2Test类在同一个包里。这个假定是正 确的,于是编译器来寻找com.web_tomorrow.CP1Test,但它没有地方可以找,因为我们已经把类搜索路径
明确的指定成了“”(也就是空)。 
     你可能认为,只要告诉编译器在当前目录下寻找就可以解决这个问题。在Unix和Windows系统中,“当前目录”的标准符号都是一个点号(.),也就是这样的命令: 
     javac -classpath "." CPTest2.java 
     Fail Againt!跟刚才的例子完全一样,现在的问题是虽然CPTest1.java在当前目录下,但它实现的类不是CPTest1,而是 com.web_tomorrow.CPTest1,编译器将在当前目录下寻找目录com/web_tomorrow。也就是说,它在目录
[root]/com/web_tomorrow/com/web_tomorrow中寻找一个Java源文件或类文件,它们事实上根本不存在,于是出错。 
     为了让编译器工作正常,我们不能让类搜索路径指向包含CPTest1的目录,而是按照Java标准中`package name = directory name'的规则,给类搜索路径指定编译器能找到CPTest1的根目录。这样才能工作,虽然不太好看: 
     javac -classpath "../.." CPTest2.java 
     在考虑如何变得不难看之前,看一下这个例子(仍在同一目录下) 
     javac -classpath "" CPTest1.java CPTest2.java 
     尽管classpath为空,这次却能工作。这是因为Java编译器会在命令行中明确列出的所有源代码中查找引用。如果要编译同一目录下的多个类,有一种很简单的方式: 
     javac -classpath "" *.java 
     '*.java'扩展为当前目录下所有.java文件的列表。这就说明为什么一次编译多个文件会成功,而同样的文件一个一个的编译却失败。 
     编译CPTest2有一个更方便的方法: 
     cd [root] 
     javac -classpath "." com/web_tomorrow/CPTest2.java 
     这次我们为CPtest2.java指定了完整的路径,而在-classpath选项中使用了'.'。另外,我们没有告诉编译器在当前目录下寻找文件,而是让它从当前目录开始搜索。
     因为我们要找的类是com.web_tomorrow.CPTest1,编译器将在./com/web_tomorrow(也就是说当前目录下的com/web_tomorrow子目录)下寻找。这才是CPTest1.java正确的位置。 
     事实上,尽管我在命令行只指定了CPTest2,但事实上CPTest1同时也会被编译。编译器在正确的位置找到这个.java文件,但它不能判定这个.java文件是否包含正确的类,所以它编译这个文件。但请注意如果是: 
     cd [root] 
     javac -classpath "." com/web_tomorrow/CPTest1.java 
     就不会导致CPTest2.java被编译,因为编译器编译CPTest1时不需要知道CPTest2的任何事情。 
     类文件与.java文件分开的情况 
     到目前为止所有成功的例子都把输出的.class文件放到.java文件同样的位置,这是一种比较简单的模式,应用非常广泛。但很多开发者喜欢 把源文件和生成的文件分开,因此它必须告诉编译器为.class文件维护不同的目录。下面我们来看看这对类搜索路径有何影响。 
     首先我们删除刚才几个例子产生的所有.class文件。我们还要有一个新的目录来存放生成的.class文件。命令行方式下的操作过程如下: 
     cd [root] 
     rm com/web_tomorrow/*.class 
     mkdir classes 
     如果你用Windows系统,别忘了把'/'替换成'\',现在的目录结构如下:

[root] com 
     web_tomorrow 
     CPTest1.java 
     CPTest2.java classes 
     现在编译CPTest1.java,指定类文件的目标目录(通过-d选项) 
     cd [root] 
     javac -d classes -classpath "" com/web_tomorrow/CPTest1.java 
     成功,但你会注意到,.class文件根本不是直接放在classes目录中,而是有了一个新的目录结构:

[root] com 
     web_tomorrow 
     CPTest1.java 
     CPTest2.java 
     classes com 
     web_tomorrow 
     CPTest1.class 
     编译器建立了一个符合包结构的目录结构,这很有用,我们马上就会看到。当开始编译CPTest2.java时我们有两个选择,第一种是像上面一 样,让编译器同时也编译一次CPTest1;另一种是用-classpath选项指定刚才编译好的.class文件,这种方法更好一点,因为我们不必再来 编译一遍CPTest1: 
     cd [root] 
     javac -d classes -classpath classes com/web_tomorrow/CPTest2.java      
     完成之后,我们的目录结构如下:

[root] com 
     web_tomorrow 
     CPTest1.java 
     CPTest2.java 
     classes 
     com 
     web_tomorrow 
     CPTest1.class 
     CPTest2.class 
     当然我们也可以在同一条命令中编译两个.java文件,结果完全相同。
4.classpath中的JAR打包文件 
     Java编译器和运行环境不仅可以在独立文件中搜索类,还可以在JAR打包文件中进行查找。一个JAR打包文件可以维护它自己的目录结 构,Java按照跟普通目录结构完全相同的方式,`directory name = package name',进行搜索。由于JAR本身就是一个目录,所以在类搜索路径中包含JAR打包文件时,路径必须引用JAR本身,而不是它所在的目录。如果我在目 录/myclasses下有一个JAR myclasses.jar,我需要指定:javac -classpath /myclasses/myclasses.jar ...而不仅仅是目录myclasses。
5.多个类搜索目录 
     在上面的例子中,每次我们都只让javac在一个目录下搜索。实际工作中,你的类搜索路径会包含很多目录和JAR文件。Javac的-classpath选项允许指定多个位置,但请注意,它的具体语法在Unix系统和Windows系统中稍有区别。 
     在Unix系统中是: 
     javac -classpath dir1:dir2:dir3 ... 
     而Windows系统则是: 
     javac -classpath dir1;dir2;dir3 ... 
     这是因为Windows使用冒号(:)作为文件名的一部分,因此不能作为文件名分隔符。当然目录分隔符也不一样:Unix的正斜杠(/)和Windows的反斜杠(\)。
6.系统classpath 
     除了在javac命令指定类搜索路径外,我们还可以使用'系统'类路径。如果命令中没有指定特定的路径,Java编译器和JVM都使用系统路径。在Unix和Windows系统中,系统路径都通过环境变量设置。

例如在使用bash shell的Linux系统中:
     CLASSPATH=/myclasses/myclasses.jar;export CLASSPATH 
     在Windows中: 
     set CLASSPATH=c:\myclasses\myclasses.jar 
     这是暂时改变系统变量CLASSPATH的好方法,但如果你想这些变化一直保留下来,你就需要针对你的系统做一些修改。例如在Linux系统 中,我会将这个命令放到我目录下的文件.bashrc中。而在Windows 2000/NT中可以通过‘控制面板’来修改。 
     如果你有很多随时用到的JAR,设置系统变量CLASSPATH就显得尤为重要。比如说,如果我在用Sun的J2EE参考实现开发EJB应用, 所有EJB相关的类都发布在一个叫做“j2ee.jar”的JAR打包文件中,我希望这个JAR一直都在类搜索路径中。另外,还有很多人希望无论当前目录 是什么,搜索路径始终包含当前目录。所以在我的.bashrc文件中就有这样一行: 
     CLASSPATH=/usr/j2ee/j2ee.jar:.;export CLASSPATH 
     其中`.'是指'当前目录'

很容易看到命令行中的-classpath选项覆盖默认的系统类路径;它 不是扩展而是覆盖。因此如果我们既要包含默认的系统路径,又要增加一些时怎么处理呢?我们可以简单的通过-classpath选项同时列出默认值和我们要 额外增加的部分。而一个更好的办法是引用系统变量CLASSPATH。当然,这个语法对Windows系统和Unix系统是不同的。

在Unix上: 
     javac -classpath $CLASSPATH:dir1:dir2 ... 
     其中$CLASSPATH扩展为系统变量CLASSPATH。在Windows上: 
     javac -classpath %CLASSPATH%;dir1:dir2 ...

【java】【转】Java之classpath相关推荐

  1. java的环境变量classpath中加点号 ‘.’ 的作用

    java的环境变量classpath中加点号 '.' 的作用 "."表示当前目录,就是编译或者执行程序时,你的.class文件所在的目录: 当找.class文件时,先去" ...

  2. java 启动程序设置classpath/加载jar、类的方式

    目录 前言 java 类加载器与路径 设置 bootclasspath 设置 Extensions JAR files 设置 classpath jar -jar 方式启动时,设置classpath ...

  3. 关于 java.library.path、classpath、path 以及 java 程序一些依赖相关的理解

    介绍 java.library.path:Java 的属性.启动时通过 -Djava.library.path 指定:用来指定非 java 类包的位置.如:dll,so. classpath:Java ...

  4. java项目中的classpath到底是什么

    java项目中的classpath到底是什么 在java项目中,你一定碰到过classpath,通常情况下,我们是用它来指定配置/资源文件的路径.在刚开始学习的时候,自己也糊里糊涂,但是现在,是时候弄 ...

  5. 介绍java -cp java -jar的区别

    java -cp 和 -classpath 一样,是指定类运行所依赖其他类的路径,通常是类库,jar包之类,需要全路径到jar包,window上分号";" java -cp &am ...

  6. linux java maven_Linux——java+tomcat+maven 安装

    一.java 1.清理系统自带的 jdk 查看系统带的 java jdk rpm -qa | grep jdk 卸载命令 sudo yum remove jdk的名字 下载: wget --no-ch ...

  7. lr java vuser_LR Java脚本编写方法

    之前在某一家银行也接触过java写的性能接口脚本,最近因项目,也需编写java接口性能测试脚本,脑袋一下懵逼了,有点不知道从何入手.随后上网查了相关资料,自己又稍微总结了一下,与大家共同分享哈~ 首先 ...

  8. java demo在哪里下载_[Java教程]Java学习 (一)、下载,配置环境变量,第一个demo...

    [Java教程]Java学习 (一).下载,配置环境变量,第一个demo 0 2016-03-01 22:00:18 一.在 http://www.oracle.com 下载java JDK 安装到自 ...

  9. CentOS7安装Java,java高级面试笔试题

    我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码或搜索下图红色VX号,加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起 ...

  10. nohup java - cp_nohup java - cp

    nohup: nohup Command [ Arg - ] [ & ] 不挂断地运行命令,要运行后台中的 nohup 命令,添加 & ( 表示"and"的符号)到 ...

最新文章

  1. 深度学习中的注意力机制(二)
  2. 2022年人才引进,哪些高校待遇高?
  3. 全球首次!中国黑客通过安全漏洞远程攻破特斯拉,可在行驶中“帮”你刹车...
  4. alibaba cloud is expensive
  5. 取代ZooKeeper!高并发下的分布式一致性开源组件StateSynchronizer
  6. python是如何登上编程语言排行榜榜首的
  7. mysql 编译cpu数量_适合MySQL的Xeon 55XX系列CPU编译参数
  8. golang 相互引用_Golang与C互用以及调用C的so动态库和a静态库
  9. Python压缩新文件到已有ZIP文件
  10. PHP学习总结(8)——PHP入门篇之WAMPServer集成环境安装和配置
  11. Lesson 3 Part 1 Locally weighted regression
  12. python模块安装
  13. 物联网环境下信息安全问题与对策
  14. 电信网通证实台湾地震影响内地访问国际网站(12月27日)
  15. 如何从dump文件中提取出C#源代码学习通http://www.bdgxy.com/
  16. 解决开机提示High Severity Error问题
  17. IDEA 导入Junit.jar 包 ,使用 Junit 单元测试过程
  18. 2023武汉集训总结
  19. 【编程语言】函数式编程 Functional Programming
  20. CODING 代码资产安全系列之 —— 构建全链路安全能力,守护代码资产安全

热门文章

  1. 第二课 --- git的(管理修改和撤销修改、删除文件)
  2. django ---- models继承
  3. Canvas入门-利用Canvas绘制好玩的电子时钟
  4. android textview改变部分文字的颜色和string.xml中文字的替换及部分内容设置颜色、字体、超链接、图片...
  5. AI强势来袭,锁上手机就真的安全了吗?
  6. [ 一起学React系列 -- 6 ] 秘术之时间旅行-1
  7. 在centos7上编译安装nginx
  8. Java实现最小堆一
  9. 成为JavaGC专家(1)—深入浅出Java垃圾回收机制
  10. 构建JSE 开发环境(图文并茂)