classpath详解
在dos下编译java程序,就要用到classpath这个概念,尤其是在没有设置环境变量的时候。classpath就是存放.class等编译后文件的路径。
javac:如果当前你要编译的java文件中引用了其它的类(比如说:继承),但该引用类的.class文件不在当前目录下,这种情况下就需要在javac命令后面加上-classpath参数,通过使用以下三种类型的方法 来指导编译器在编译的时候去指定的路径下查找引用类。
(1).绝对路径:javac -classpath c:/junit3.8.1/junit.jar Xxx.java
(2).相对路径:javac -classpath ../junit3.8.1/Junit.javr Xxx.java
(3).系统变量:javac -classpath %CLASSPATH% Xxx.java (注意:%CLASSPATH%表示使用系统变量CLASSPATH的值进行查找,这里假设Junit.jar的路径就包含在CLASSPATH系统变量中)
javac 绝对路径的使用:
javac:假设你要编译的类文件名叫:HelloWorld.java,其完全路径为:D:/java/HelloWorld.java。但你所在的当前目录是:C:/Documents
and Settings/peng>。如果想在这里执行编译,会有什么结果呢?
(1).C:/Documents and Settings/peng> javac HelloWorld.java 这时编译器会给出如下的错误提示信息:
error: cannot read: HelloWorld.java
这是因为默认情况下javac是在当前目录下查找类文件,很明显这个路径不是我们存放类文件的地方,所以就会报错了
(2).C:/Documents and Settings/peng>javac D:/java/HelloWorld.java
这时编译成功。
所以,只要你执行javac命令的目录不是类文件存放的目录,你就必须在javac命令中显式地指定类文件的路径。
java -classpath的使用:
java:假设我们的CLASSPATH设置为:D:/peng/java/pro ,在该目录下有三个文件:HelloWorld.java /
HelloWorldExtendsTestCase / HelloWorldExtendsHelloWorld。这三个文件的类声明分别如下:
HelloWorld.java :public class HelloWorld
HelloWorldExtendsHelloWorld.java :public class HelloWorldExtendsHelloWorld extends HelloWorld
HelloWorldExtendsTestCase.java:public class HelloWorldExtendsTestCase extends junit.framework.TestCase
假设我们已经按照上面关于javac -classpath和javac 绝对路径的使用,顺利地完成了三个文件地编译。现在我们在C:/Documents and Settings/peng>目录下执行这三个.class文件
(1).C:/Documents and Settings/peng>java HelloWorld
Hello World
可以看到执行成功。为什么我们在 C:/Documents
and
Settings/peng>执行命令,JVM能够找到D:/peng/java/pro/HelloWorld.class文件呢?这是因为我们配置了系统变量CLASSPATH,并且指向了目录:D:/peng/java/pro
。所以JVM会默认去该目录下加载类文件,而不需要指定.class文件的绝对路径了。
(2).C:/Documents and Settings/peng>java HelloWorldExtendsHelloWorld
Hello World
可以看到执行成功了。HelloWorldExtendsHelloWorld继承了HelloWorld类,所以在执行时JVM会先查找在CLASSPATH下是否存在一个HelloWorld.class文件,因为我们已经成功编译了HelloWorld 类了,所以可以成功执行HelloWorldExtendsHelloWorld.class
(3).C:/Documents and Settings/peng>java HelloWorldExtendsTestCase
Exception in thread "main" java.lang.NoClassDefFoundError: junit/framework/TestCase
可以看到程序抛出异常了,提示找不到junit.framework.TestCase文件。为什么同样在:/peng/java/pro 下,HelloWorldExtendsHelloWorld.class就可以成功执行,而这个就不行了呢?这是因为:
junit.framework.TestCase.class文件并不存在于当前目录下,所以为了能够让程序成功运行,我们必须通过指定CLASSPATH的方式,让JVM可以找到junit.framework.TestCase这个类,如(4):
(4). C:/Documents and Settings/peng>java -classpath %CLASSPATH% HelloWorldExtendsTestCase
Hello World
总结:
(1).何时需要使用-classpath:当你要编译或执行的类引用了其它的类,但被引用类的.class文件不在当前目录下时,就需要通过-classpath来引入类
(2).何时需要指定路径:当你要编译的类所在的目录和你执行javac命令的目录不是同一个目录时,就需要指定源文件的路径(CLASSPATH是用来指定.class路径的,不是用来指定.java文件的路径的)
JAVA获取classpath路径:
public URL getResource (String
name);
public InputStream getResourceAsStream (String
name);
这里name是资源的类路径,它是相对与“/”根路径下的位置。getResource得到的是一个URL对象来定位资源,而getResourceAsStream取得该资源输入流的引用保证程序可以从正确的位置抽取数据。
但是真正使用的不是ClassLoader的这两个方法,而是Class的
getResource和getResourceAsStream方法,因为Class对象可以从你的类得到(如YourClass.class或
YourClass.getClass()),而ClassLoader则需要再调用一次YourClass.getClassLoader()方法,不过根据JDK文档的说法,Class对象的这两个方法其实是“委托”(delegate)给装载它的ClassLoader来做的,所以只需要使用
Class对象的这两个方法就可以了。
因此,直接调用 this.getClass().getResourceAsStream(String
name) ;获取流,静态化方法中则使用ClassLoader.getSystemResourceAsStream (String
name) ; 。
下面是一些得到classpath和当前类的绝对路径的一些方法。你可能需要使用其中的一些方法来得到你需要的资源的绝对路径。
1.this.getClass().getResource("")
得到的是当前类class文件的URI目录。不包括自己!
如:file:/D:/workspace/jbpmtest3/bin/com/test/
2.this.getClass().getResource("/")
得到的是当前的classpath的绝对URI路径 。
如:file:/D:/workspace/jbpmtest3/bin/
3.this.getClass() .getClassLoader().getResource("")
得到的也是当前ClassPath的绝对URI路径 。
如:file:/D:/workspace/jbpmtest3/bin/
4.ClassLoader.getSystemResource("")
得到的也是当前ClassPath的绝对URI路径 。
如:file:/D:/workspace/jbpmtest3/bin/
5.Thread.currentThread().getContextClassLoader ().getResource("")
得到的也是当前ClassPath的绝对URI路径 。
如:file:/D:/workspace/jbpmtest3/bin/
6.ServletActionContext.getServletContext().getRealPath(“/”)
Web应用程序 中,得到Web应用程序的根目录的绝对路径。这样,我们只需要提供相对于Web应用程序根目录的路径,就可以构建出定位资源的绝对路径。
如:file:/D:/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/WebProject
注意点:
1.尽量不要使用相对于System.getProperty("user.dir")当前用户目录的相对路径。这是一颗定时炸 弹,随时可能要你的命。
2.尽量使用URI形式的绝对路径资源。它可以很容易的转变为URI,URL,File对象。
3.尽量使用相对classpath的相对路径。不要使用绝对路径。使用上面ClassLoaderUtil类的public
static URL getExtendResource(String
relativePath)方法已经能够使用相对于classpath的相对路径定位所有位置的资源。
4.绝对不要使用硬编码的绝对路径。因为,我们完全可以使用ClassLoader类的getResource("")方法得到当前classpath的绝对路径。如果你一定要指定一个绝对路径,那么使用配置文件,也比硬编码要好得多!
获得CLASSPATH之外路径的方法:
URL base = this.getClass().getResource(""); //先获得本类的所在位置,如/home/popeye/testjava/build/classes/net/
String path = new File(base.getFile(), "……/……/……/"+name).getCanonicalPath(); //就可以得到/home/popeye/testjava/name
另外,如果从ANT启动程序,this.getClass().getResource("")取出来的比较怪,直接用JAVA命令行调试就可成功。
classpath详解的更多相关文章
- PATH环境变量和CLASSPATH环境变量详解
大凡装过JDK的人都知道要安装完成后要设置环境变量,可是为什么要设置环境变量呢?环境变量有什么作用? 1)PATH详解: 计算机安装JDK之后,输入“javac”“java”之类的命令是不能马上被计算 ...
- Eclipse和MyEclipse工程描述符.classpath和.project和.mymetadata详解aaaaaa(转)
Eclipse和MyEclipse工程描述符.classpath和.project和.mymetadata详解(转) (2012-03-28 15:06:54) 转载▼ 标签: .mymetadata ...
- [转]JAVA环境变量JAVA_HOME、CLASSPATH、PATH设置详解
[转] JAVA环境变量JAVA_HOME.CLASSPATH.PATH设置详解 - dreamman的日志 - 网易博客http://blog.163.com/dreamman_yx/blog/st ...
- 详解path和classpath的区别
详解path和classpath的区别 path的作用 path是系统用来指定可执行文件的完整路径,即使不在path中设置JDK的路径也可执行JAVA文件,但必须把完整的路径写出来,如C:\Progr ...
- Android消息传递之EventBus 3.0使用详解
前言: 前面两篇不仅学习了子线程与UI主线程之间的通信方式,也学习了如何实现组件之间通信,基于前面的知识我们今天来分析一下EventBus是如何管理事件总线的,EventBus到底是不是最佳方案?学习 ...
- (十)Maven依赖详解
1.何为依赖? 比如你是个男的,你要生孩子,呸呸呸...男的怎么生孩子,所以你得依赖你老婆,不过也不一定咯,你也可以依赖其她妹子. 我们在平时的项目开发中也是同理,你需要依赖一些东西才能实现相应的功能 ...
- Web.xml详解(转)
这篇文章主要是综合网上关于web.xml的一些介绍,希望对大家有所帮助,也欢迎大家一起讨论. ---题记 一. Web.xml详解: (一) web.xml加载过程(步骤) 首 ...
- 搭建Android开发环境附图详解+模拟器安装(JDK+Eclipse+SDK+ADT)
——搭建android开发环境的方式有多种,比如:JDK+Eclipse+SDK+ADT或者JDK+Eclipse+捆绑好的AndroidSDK或者Android Studio. Google 决定将 ...
- 史上最全的maven的pom.xml文件详解
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
随机推荐
- (一)Struts2 基础
一.Struts简介 1.1 历史 虽然Struts 2号称是一个全新的框架,但这仅仅是相对Struts 1而言.Struts 2与Struts 1相比,确实有很多革命性的改进,但它并不是新发布的新框 ...
- matlab cell
cell元包是matlab中提供的一种数据类型,功能强大. 关于cell的创建: 1.跟一般创建举证一样,直接使用C = {A B D E}这种形式,不过这里把"[]"改成了}&q ...
- vue+element下拉树选择器
项目需求:输入框点击弹出树形下拉结构,可多选或者单选. 解决方案:1.使用layui formSelect多选插件 2.基于vue+elementui 下拉框和树形控件组合成树形下拉结构 <el ...
- zabbix-设置邮箱预警
设置预警系统 机器是被监控上了,但是出了问题怎么通知呢?之前学过监控软件的都知道可以使用报警机制啊,如果监控平台zabbix server发现某个机器异常了,可以给运维管理员发邮件啊,通过邮件通知管理 ...
- 抓包分析工具web版——capanalysis
1.下载安装 官网上,安装在Ubuntu上 2.使用教程 https://blog.51cto.com/chenguang/1325742
- 安卓直连SQLSEVER数据库
1.导入连接SQLSEVER的jar包:可以支持android的SQL驱动(如:jtds-1.2.7.jar) 2.编写连接数据库的工具类 import java.lang.reflect.Field ...
- Tomcat之session解决方案
目录 session方案及配置 一.session绑定 二.session复制 三.使用memcached解决session问题 四.使用redis解决session问题 五.memcached和re ...
- Vs2017 NetCode Mvc EF Mysql 整合2
1 NetCode EF整合 代码 3 源代码 https://github.com/chxl800/EFMysqlDemo 1.1 项目文件结构 1.2 NuGet MySql.Data.Ent ...
- Kinect for Windows SDK开发入门(二):基础知识 上
原文来自:http://www.cnblogs.com/yangecnu/archive/2012/03/31/KinectSDK_Application_Fundamentals_Part1.htm ...
- 【转】Linux下常用压缩 解压命令和压缩比率对比
https://www.cnblogs.com/joshua317/p/6170839.html 常用的格式有:tar, tar.gz(tgz), tar.bz2, 不同方式,压缩和解压方式所耗CPU ...