JAVA编程解析之classpath的深入理解

Python010

JAVA编程解析之classpath的深入理解,第1张

现在的JAVA编程是内容最多也是难度最大的程序 对于每一个程序员来说 对每个知识都要进行深入的理解 这也是一个循序渐进的一个过程 本文章主要对于classpath作一个深入的解析 希望对各位朋友们有所帮助

jvm的类加载分三中方式

系统级别 rt jar

扩展级别 java_home/jre/lib/ext/目录下的jar文件

应用级别 环境变量中的classpath或javac   java中的参数指定java   classpath        …

或者自己写ClassLoader加载

前面 中是JVM自动处理 其中第二种是为了处理Java的classpath灾难而提供的解决方案

实际上java虚拟机是由java luncher初始化的 也就是java(或java exe)

这个程序来做的    虚拟机按以下顺序搜索并装载所有需要的类

   引导类    组成java平台的类    包含rt jar和i n jar中的类

   扩展类    使用java扩展机制的类 都是位于扩展目录($JAVA_HOME/jre/lib/ext)

中的 jar档案包

   用户类    开发者定义的类或者没有使用   java   扩展机制的第三方产品    你必须在

命令行中使用   classpath   选项或者使用   CLASSPATH   环境变量来确定这些类的位置    我

们在上面所说的用户自己的类就是特指这些类

这样    一般来说    用户只需指定用户类的位置    引导类和扩展类是 自动 寻找的

当你的程序需要第三方的类库支持    而且比较常用    就可以采用此种方法 比如常

用的数据库驱动程序    写   servlet   需要的   servlet   包等等    设置方法就是在环境变量中

加入   CLASSPATH    然后就可以直接编译运行了 而你的程序只用了些基础类 寻找时 就用不

著必须设定它

在执行Java程序的时候 会自动加载程序用中需要的在rt jar和其他java_home\jre\lib中包含的 jar文件中包含的Java基础类库和一些扩展类库 这些都是JVM自动处理的 对用户来说是透明的

如果Java程序中使用到了一些应用级别的类(如第三方的类) 可以在javac和java中的 classpath选项中指定它们的搜索路径 或者是自 己写ClassLoader加载 另外也可以设置ClassPath环境变量 在里面指定那些蝶阀应用级别的类的搜索路径

设置ClassPath环境变量不是必须的 只是为了方便使用 设置了ClassPath JDK就会按ClassPath制定的路径去搜索需要的应用级别的类 而不必每一次都使用 classpath选项或自己写ClassLoader

还有需要注意的就是 如果相关的类就在当前工作目录下的话 上面 种方法都可以不要 因为JDK系统会首先搜索会在当前的工作目录中搜索程序相关的类 (在jdk 下已经验证)

lishixinzhi/Article/program/Java/hx/201311/26234

这里的java程序运行过程,是指我们编译好代码之后,在命令行开始执行java xxx命令,到java程序开始执行起来的这一过程,我们称其为运行时。

第一步,操作系统解析我们输入的java xxx命令,根据PATH中所配置的jrd路径找的其bin目录下的java.exe程序(这个程序是用c语言写的,源码在jdk的src文件中的laucher目录下),然后再初始化一些java参数(比如classpath、虚拟机参数等)。

第二步,java.exe程序根据上一步读入的虚拟机参数,分配内存并启动jre/bin目录下client目录或者server目录(哪个目录取决于第一步中的虚拟机参数)下的jvm.dll,java虚拟机开始启动。

第三步,java虚拟机初始化内存,产生bootstrap classloader,这个类加载器负责加载java API(jvm+java API被称为java运行时),其实这些jar包主要分布在jre/lib下,这些我们可以通过在java命令后加-verbose:class(如下图),可见第一个被载入的java类是Object类。

[java] view plain copy

C:\Documents and Settings\nomouse>java -verbose:class

[Loaded java.lang.Object from shared objects file]

[Loaded java.io.Serializable from shared objects file]

[Loaded java.lang.Comparable from shared objects file]

[Loaded java.lang.CharSequence from shared objects file]

[Loaded java.lang.String from shared objects file]

[Loaded java.lang.reflect.GenericDeclaration from shared objects file]

[Loaded java.lang.reflect.Type from shared objects file]

[Loaded java.lang.reflect.AnnotatedElement from shared objects file]

[Loaded java.lang.Class from shared objects file]

[Loaded java.lang.Cloneable from shared objects file]

[Loaded java.lang.ClassLoader from shared objects file]

[Loaded java.lang.System from shared objects file]

[Loaded java.lang.Throwable from shared objects file]

[Loaded java.lang.Error from shared objects file]

[Loaded java.lang.ThreadDeath from shared objects file]

[Loaded java.lang.Exception from shared objects file]

[Loaded java.lang.RuntimeException from shared objects file]

[Loaded java.security.ProtectionDomain from shared objects file]

[Loaded java.security.AccessControlContext from shared objects file]

...

第四步,bootstrap classloader载入完java API后,还会负责载入ExtClassLoader并生成一个实例,它继承于ClassLoader类,负责载入jre/lib/ext下的jar包(所以有时候需要把servlet.jar包加进去,相当于一个不配置在classpath中就可以默认访问的公共jar目录),到这里,java虚拟机默认加载类工作完成,java虚拟机找到我们指定的Class,加载这个类(所谓自定义类加载,是指我们自己写的java类、以及我们引入的一些第三方jar包的加载方式,只有代码中运行到类的时候才回去加载,我们可以实现自己的ClassLoader类,用来加载我们自己的类,如果我们没有实现自己的类加载器,上面说的ExtClassLoader会默认载入AppClassLoader并生成一个实例,由这个类加载器来进行加载),然后找到这个类的main方法,启动程序。