ClassPath 解惑,到底什么是Classpath?

dos下编译java程序,就要用到classpath这个概念,尤为是在没有设置环境变量的时候。classpath就是存放.class等编译后文件的路径。 java

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系统变量中)
web

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 -classpathjavac 绝对路径的使用,顺利地完成了三个文件地编译。如今咱们在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文件的路径的
) 
app

 

JAVA获取classpath路径: eclipse

ClassLoader 提供了两个方法用于从装载的类路径中取得资源:

        public URL
  getResource (String name);  
        public InputStream
  getResourceAsStream (String name);  

      
这里name是资源的类路径,它是相对与"/"根路径下的位置。getResource获得的是一个URL对象来定位资源,而getResourceAsStream取得该资源输入流的引用保证程序能够从正确的位置抽取数据。
      
可是真正使用的不是ClassLoader的这两个方法,而是Class getResourcegetResourceAsStream方法,由于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形式的绝对路径资源。它能够很容易的转变为URIURLFile对象。

3.
尽可能使用相对classpath的相对路径。不要使用绝对路径。使用上面ClassLoaderUtil类的public static URL getExtendResourceString 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命令行调试就可成功。
webapp

 

PS:以上内容不少来自转载和本身的部分总结。 ui

相关文章
相关标签/搜索