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 ...
随机推荐
- CSPS2019游记
Day1: T1:格雷码?看一眼感觉是结论题,但是没头绪推不出来,硬刚40min想到$\oplus$切了. 但是没写unsigned挂了五分... T2:全场爆切人均50的题,就我一个写挂了35pts ...
- 经典SQL数据库面试题以及答案—Oracle版本-SQL全部在plsql开发编写-欢迎提问
Student(Sno,Sname,Sage,Ssex) 学生表 S1:学号:Sname:学生姓名:Sage:学生年龄:Ssex:学生性别 Course(Cno,Cname,T1) 课程表 C1,课程 ...
- Redis 测试 数据类型
- MVC,MVP 和 MVVM 的图示(原理)
一.MVC MVC模式的意思是,软件可以分成三个部分. 视图(View):用户界面. 控制器(Controller):业务逻辑 模型(Model):数据保存 各部分之间的通信方式如下. View 传送 ...
- leetcode-64. 最小路径和 · vector + DP
题面 Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right wh ...
- linux内存管理初学
虚拟内存模型 Linux 内核本身并不运行在虚拟空间中,其使用的是物理寻址模式. 物理内存被分割为界面,一个内存页面的大小由PAGE_SIZE宏决定. 虚拟地址空间的方式使程序员可以将巨大的结构用于连 ...
- MacOS文本编辑无法打不开GB18030
不要直接双击打开 而是 打开sublime text或者其他文本编辑后,从软件里面的open选型打开
- 《浏览器工作原理与实践》<08>调用栈:为什么JavaScript代码会出现栈溢出?
在上篇文章中,我们讲到了,当一段代码被执行时,JavaScript 引擎先会对其进行编译,并创建执行上下文.但是并没有明确说明到底什么样的代码才算符合规范. 那么接下来我们就来明确下,哪些情况下代码才 ...
- DNS理解
前言 英译汉的时候会掩盖很多本质,导致很多问题稀里糊涂,问的人不知道怎么说,回答的人也是答非所问. DNS是Domain Name System缩写,不是Domain Name Server,或者Do ...
- WebMvcConfig
package cn.xx.yy; import java.util.ArrayList;import java.util.HashMap;import java.util.List;import j ...