`
littie1987
  • 浏览: 130984 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Java中类的加载

    博客分类:
  • Java
阅读更多

      今天遇到一个奇怪的现象,我把环境变量里的classpath删除掉之后仍然可以执行java程序(path属性没有删除)。

后来终于明白了,这是java的类加载顺序支配的。

      java虚拟机加载一个类分为以下三种顺序:

      1:Bootstrap   2:Extension   3:Users  

     

     一: Bootstrap:在java启动时载入的类,主要是一些重要的jdk的jar文件。比如rt.jar。这个jar文件包含了jdk的一些基础类库,比如我们熟知的java.lang,java.util等等都包含在rt.jar文件里。这个文件是Bootstrap负责加载的,也就是说我们不需要在项目中手动导入这个jar文件,也不需要在classpath里将他添加进去(他的实际目录为%JAVA_HOME%\jre\bin\rt.jar)。所以就可以解释我遇到的那个奇怪的问题了。没有classpath,一些基本的程序还是可以运行的。当然,Bookstrap不止装载rt.jar一个jar文件。要想知道他都加载了哪些类,可以用如下方法打印:System.out.println(System.getProperty("sun.boot.class.path"));。打印结果如下:

C:\Program Files\Java\jdk1.6.0_05\jre\lib\resources.jar;C:\Program Files\Java\jd
k1.6.0_05\jre\lib\rt.jar;C:\Program Files\Java\jdk1.6.0_05\jre\lib\sunrsasign.ja
r;C:\Program Files\Java\jdk1.6.0_05\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.
6.0_05\jre\lib\jce.jar;C:\Program Files\Java\jdk1.6.0_05\jre\lib\charsets.jar;C:
\Program Files\Java\jdk1.6.0_05\jre\classes

 也就是说,在java启动的时候就已经加载了这么多的类。只要你的程序引用到的类都在这些jar文件里有的话,那就不需要设置什么classpath,更不手动需要导入jar包。

 

二:Extension:如果在Bootstrap的路径里找不到所要的类怎么办?那么这时java虚拟机就会去ext目录下找。具体的目录为%JAVA_HOME%\jre\lib\ext。我们可以试验一下。在ext目录里有一个dt.jar,里面有一个类:javax.swing.BoxBeanInfo。如果我们尝试去加载这个类,按照加载顺序,它会去ext目录下找。看一个程序:

public class tet{
public static void main(String[] args)throws ClassNotFoundException
{

ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class lo = loader.loadClass("javax.swing.BoxBeanInfo");
System.out.println(lo.getClassLoader());
		
}
}

 它的打印结果是:sun.misc.Launcher$ExtClassLoader@addbf1,很明显,他是由ExtClassLoader类加载器进行加载的。因为如果是Bootstrap加载的类,在打印它的类加载器的时候会是null。

 

三:Users :如果所需要的类在以上的目录里都没有,比如你想要一个spring的BeanFactory类,那JDK本身是不可能带的,所以必须由外部导入。由外部导入又有好几种方法,但是java虚拟机的搜索顺序是:

      1:默认的User   classes   .   (dot)   就是指当前目录。

      2:系统变量   CLASSPATH   所指定的类库,该变量覆盖(override)默认的User   classes。

      3:用命令行参数   -cp   或   -classpath指定的类库。这个时候覆盖默认的User   classes   和CLASSPATH变量。

      4:通过-jar   参数指定的jar文件。此时覆盖上面的三种情况,如果使用这种情况,所有的类文件必须来自指定的jar            文件

由此可见,我们平时将一个jar文件放到当前工程的lib目录下,就是第一种搜索顺序,所以如果你不嫌麻烦,完全可以将他设置到classpath之下,当然我们实际不会这么干。此时如果我们打印它的类加载器就应该是ApplicationClassLoader。

 

另外需要说明的是:ApplicationClassLoader的父加载器是ExtClassLoader,ExtClassLoader的父加载器是Bootstrap。但是,打印Bootstrap的类的加载器的的时候往往显示null,好像没有一样,其实打印null就表示是Bootstrap。另外,java的类加载是采用委托机制,即遇到一个类要加载,它不会用子加载器进行加载,而是将请求上述到父加载器,如果父加载器没有找到,就再上述到更高一级的父加载器,一直到Bootstrap为止。如果没有找到,就按照刚才的路径往下转。直到找到为止。所以,如果一个类在classpath里有,在Ext目录下也有,那么加载他的类加载器一定是ExtClassLoader。

我们再来看上面的那个程序:

public class tet{
public static void main(String[] args)throws ClassNotFoundException
{

ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class lo = loader.loadClass("javax.swing.BoxBeanInfo");
System.out.println(lo.getClassLoader());
		
}
}

 

这次我们将在ext目录下的dt.jar文件剪切掉,将他放到%JAVA_HOME%\lib目录下,并且将他设置到classpath环境变量里面。这次我们再打印的话,结果为:sun.misc.Launcher$AppClassLoader@19821f,他的类加载器显然已经变了。这就证明了在classpath里的类是有ApplicationClassLoader加载的,他属于用户自己的类。

分享到:
评论

相关推荐

    Java虚拟机类加载顺序

    Java虚拟机类加载顺序,Java虚拟机类加载顺序,Java虚拟机类加载顺序

    java类加载器实例

    它使得 Java 类可以被动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的。Java Applet 需要从远程下载 Java 类文件到浏览器中并执行。现在类加载器在 ...

    自定义Java类加载器

    看完一个Java加载原理教程后,写了这个自己的类加载器,作个笔记,以便以且使用

    springboot+java类热加载

    springboot 、java类热加载、jarinjar、动态编译、自动引用依赖

    Java中类加载过程全面解析

    主要介绍了Java中类加载过程全面解析,具有一定参考价值,需要的朋友可以了解下。

    Java类加载原理解析

    每个java开发人员对java.lang.ClassNotFoundExcetpion这个异常肯定都不陌生,这背后就涉及到了java技术体系中的类加载。Java的类加载机制是java技术体系中比较核心的部分,虽然和大部分开发人员直接打交道不多,但是...

    深入研究Java类加载机制 深入研究Java类加载机制

    深入研究Java类加载机制 深入研究Java类加载机制 深入研究Java类加载机制 深入研究Java类加载机制

    java类加载器

    ClassLoader 三种类加载方式 Boostrap Extenxsion 以及Application ClassLoad分别适用的场景

    java 类加载器 加密

    java 类加密 使用类加载器解密加载类 反射执行main

    java类加载器学习三、类加载器的委托模式

    java类加载器学习三、类加载器的委托模式

    Java类加载器.pdf

    Java类加载器.pdf

    java类加载机制.xmind

    该文件是JVM中关于类加载机制的知识整理的思维导图,包括类加载机制概述、类加载的生命周期、加载时机、加载过程、类加载、类的初始化和实例化等几个大方面进行了讲解,其中类加载中还对JVM三种预定义类加载器进行了...

    Java类加载内幕

    类加载是java语言提供的最强大的机制之一。...然后深入探讨java虚拟机(JVM)是怎么利用类加载器读取代码,及java中类加载器的主要类型。接着用一个类加载的基本算法看一下类加载器怎么加载一个内部类。本文的下一节演

    Java反射动态加载实例类

    Java反射动态加载实例类,动态加载实例类,帮助理解反射

    Java类加载内幕详细讲解

     类加载是java语言提供的最强大的机制之一,但所有的编程人员都应该了解其工作机制,明白如何做才能让其满足我们的需要。这能有效节省我们的编码时间,从不断调试ClassNotFoundException的工作中解脱出来。

    Java类加载机制与反射-PPT

    Java的类加载机制:加载,连接,初始化。JAVA类加载器: Bootstrap ClassLoader : 根类加载器, Extension ClassLoader: 扩展类加载器, System ClassLoader : 系统类加载器, Java反射

    java类加载原理分析

    java类加载原理分析,引导类加载器,扩展类加载器,系统类加载器(也叫应用类加载器)

    类加载器(java)

    当JVM(Java虚拟机)启动时,会形成由三个类加载器组成的初始类加载器层次结构,理解类加载器:J2EE 环境下的 log4j.files

Global site tag (gtag.js) - Google Analytics