1、概述
1.1 类加载器的作用:
将Class文件加载到JVM内存中,并生成对应的java.lang.Class对象;
1.2 一旦一个类被加载到JVM内存中,它将不再被加载,如何确定一个类的唯一性?
在JVM中,通过 类本身 和 加载该类的类加载器 一同确定类的唯一性;
1.3 在JVM启动时,会形成由3个类加载器 组成的 初始类加载器层次结构:
1.3.1 Bootstrap ClassLoader
a,被称为 引导(原始、根)类加载器;
b,负责 加载 Java的核心类库;
c,此类加载器比较特殊,不是java.lang.ClassLoader的子类,由JVM自身实现;
d,查看 根类加载器加载哪些核心类库?
package com.an.classloader; import sun.misc.Launcher; import java.net.URL; public class BootstrapClassLoaderTest { public static void main(String[] args){ URL[] urLs=Launcher.getBootstrapClassPath().getURLs(); for (URL url:urLs){ System.out.println(url); } } } 结果: file:/D:/Program%20Files/Java/jdk1.8.0_201/jre/lib/resources.jar file:/D:/Program%20Files/Java/jdk1.8.0_201/jre/lib/rt.jar file:/D:/Program%20Files/Java/jdk1.8.0_201/jre/lib/sunrsasign.jar file:/D:/Program%20Files/Java/jdk1.8.0_201/jre/lib/jsse.jar file:/D:/Program%20Files/Java/jdk1.8.0_201/jre/lib/jce.jar file:/D:/Program%20Files/Java/jdk1.8.0_201/jre/lib/charsets.jar file:/D:/Program%20Files/Java/jdk1.8.0_201/jre/lib/jfr.jar file:/D:/Program%20Files/Java/jdk1.8.0_201/jre/classes
1.3.2 Extension ClassLoader
a,称为 扩展类 加载器;
b,负责 加载JRE的扩展目录(D:\Program Files\Java\jdk1.8.0_201\jre\lib\ext) 中jar的类包;
c,通过此种方式,我们可以为Java扩展核心类库以外的新功能,只需要将自己开发的类文件打包成jar放入\jre\lib\ext目录下即可;
1.3.3 System ClassLoader
a,称为 系统(应用)类加载器;
b,负责 在JVM启动时,加载来自命令Java中的 -classpath选项 或者j ava.class.path系统属性 或者 classpath环境变量所指定的jar包、类路径;
c,如何获取系统类加载器?
可以通过ClassLoader的getSystemClassLoader来获取系统类加载器;
package com.an.classloader; import java.io.IOException; import java.net.URL; import java.util.Enumeration; public class SystemClassLoaderTest { public static void main(String[] args)throws IOException { //获取系统类加载器 ClassLoader systemClassLoader=ClassLoader.getSystemClassLoader(); System.out.println(systemClassLoader); //获取系统类加载器的加载路径---通常由CLASSPATH变量指定 Enumeration<URL> url=systemClassLoader.getResources(""); while (url.hasMoreElements()){ System.out.println(url.nextElement()); } ClassLoader extensionClassLoader=systemClassLoader.getParent(); System.out.println("系统类加载器--父类--扩展类加载器:"+extensionClassLoader); ClassLoader bootstrapClassLoader=extensionClassLoader.getParent(); System.out.println("扩展类加载器--父类--根类加载器:"+bootstrapClassLoader); } } 结果: sun.misc.Launcher$AppClassLoader@18b4aac2 file:/D:/Work/mydemo/target/classes/ 系统类加载器--父类--扩展类加载器:sun.misc.Launcher$ExtClassLoader@66048bfd 扩展类加载器--父类--根类加载器:null
d,自定义类加载器:
A,除了根类加载器,所有的类加载器都是ClassLoader类的子类;
B,ClassLoader类的3个核心方法:
Class loadClass(String name,boolean resolve) 根据指定的二进制名称加载类,并返回java.lang.Class对象
Class findClass(String name) 根据二进制名称查找该类
Class defineClass(String name,byte[] b,int off,int length) 将指定类的class文件读入字节数组byte[] b中,并转化为Class对象;
1.4 URLClassLoader
1.4.1 java为ClassLoader提供一个实现类URLClassLoader;
1.4.2 URLClassLoader功能比较强大,可以从本地文件系统中获取二进制文件加载类、也可以从远程主机获取二进制文件加载类;
1.4.3 URLClassLoader提供了2个构造器:
URLClassLoader(URL[] urls) 使用默认的父 类加载器创建一个ClassLoader对象,该对象将从urls指定的路径查找并加载类;
URLClassLoader(URL[] urls,ClassLoader parent) 使用指定的父 类加载器创建一个ClassLoader对象;
1.4.4 URLClassLoader对象创建好后,直接调用loadClass加载指定类;
1.4.5 案例:
package com.an.classloader; import java.net.URL; import java.net.URLClassLoader; import java.sql.Driver; public class URLClassLoaderTest { public static void main(String[] args)throws Exception{ //1、将jar拷贝到resources目录下,拷贝jar后,需要先将jar Add as Library URL[] urls=new URL[]{new URL("file:/lib/mysql-connector-java-5.1.44.jar")}; URLClassLoader urlClassLoader=new URLClassLoader(urls); Class classObj=urlClassLoader.loadClass("com.mysql.jdbc.Driver"); Driver driver =(Driver) classObj.newInstance(); System.out.println(driver); } } 结果: com.mysql.jdbc.Driver@2c8d66b2
【注意】:
file:/lib/mysql-connector-java-5.1.44.jar file:表示从本地文件系统中加载
http: 表示从互联网通过HTTP加载
ftp: 表示从互联网通过ftp加载
原文:https://www.cnblogs.com/anpeiyong/p/11027853.html