类加载器负责将.class文件(可能在磁盘上,也可能在网络上)加载到内存中,并为之生成对应的java.lang.class对象。

一、类加载器简介

  一旦某个类被类加载器载如内存中生成一个java.lang.class实例,同一个类便不会再被载入。

  类的唯一标识:再java语言中,一个类用其全限定名做唯一标识,但是在JVM中,一个类用其全限定名和它的类加器作为唯一标识

  JVM启动时,会产生三个类加载器组成的初始类加载器层次结构,分别是:

    1、Bootstrap ClassLoader:根类加载器,也被称为引导类加载器,负责加载java的核心类。那么那些是所谓的核心类呢?如果使用的是sun公司的javaJDK,则可以使用如下代码输出根加载器所加载的核心类库。

  

Java 多次点击只更新最后一次接口调用 java类只加载一次_类加载器

    编译运行,可以看到类似如下的结果:

  

Java 多次点击只更新最后一次接口调用 java类只加载一次_加载_02

    也可以指定JVM的根加载器加载其他的类,当使用java命令时,使用-Xbootclasspath选项或使用-D选项指定sun.boot.class.path系统属性值可以指定加载附加的类。

    根加载器并不是用java实现的。

    2、Extension Classloader,被称为扩展类加载器,负责加载JRE的扩展目录(%JAVA_HOME%/jre/lib/ext或者由java.ext.dirs系统属性指定的目录)种的jar包的类。

      通过这种方式,就可以为java扩展核心类以外的功能,

    3、System Classloader被称为系统(应用)类加载器,负责加载在JVM启动时加载来自java命令的-classpath选项、java.class.path系统属性,或CLASSPATH环境变量所指定的jar包或类路径。

二、类加载机制

  JVM的类加载机制主要有如下三种:

    全盘负责:当一个类加载器负责加载某个Class时,该Class所依赖的和引用的其他的Class也由该类加载器负责载入,除非显示使用另外一个加载器来载入。

    父类委托:先让父加载器试图加载该Class,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类。

    缓存机制:缓存机制将会保证所有加载过的Class对象都会被缓存,当程序中需要某个Class,类加载器先从缓存中搜寻该Class,当缓存中不存在该Class对象时,系统才会读取该类对应的二进制数据,并将其转化为Class对象,所以修改了Class文件就必须重启JVM。

    当类加载器在缓存中找不到Class,也找不到类加载器路径下的class文件时,会抛出ClassNotFoundException

三、创建自己的类加载器

  程序员可以通过继承ClassLoader类来实现自己的类加载器,然后重写findClass()方法即可。

    一般使用自己的类加载器,可实现下面一些功能:

    执行代码前自动验证数字签名。

    根据用户提供的密码解密代码,实现代码混淆器来避免反编译class文件;

    根据用户需求动态加载类;

    根据应用需求把其它数据以字节码的形式加载到应用中。

四、URLClassLoader类

  该类也是系统类加载器和扩展类加载器的父类,该类継可以从本地文件加载类,也可以从远程主机获取二进制文件来加载类

  

Java 多次点击只更新最后一次接口调用 java类只加载一次_类加载器_03

  上面的代码无需将MYSQL驱动添加进入CLASSPATH中就可以连接数据库。file: 代表本地文件系统的URL还可以以http、ftp为前缀。