共计 1193 个字符,预计需要花费 3 分钟才能阅读完成。
类加载器分类
类加载器负责根据类的全限定名将 class 文件加载到 JVM 内存,生成 Class 类的对象。它分为以下几种类型:
- Bootstrap Classloader
由 C ++ 所写,在 JVM 启动后初始化,负责加载 %JAVA_HOME%/jre/lib,-Xbootclasspath 参数指定的路径以及 %JAVA_HOME%/jre/classes 中的类 - ExtClassLoader
是 sun.misc.Launcher 的内部类,继承自 java.net.URLClassLoader->java.security.SecureClassLoader->java.lang.ClassLoader, 在 rt.jar 中,由 Bootstrap Classloader 加载,负责加载 %JAVA_HOME%/jre/lib/ext 和 java.ext.dirs 系统变量指定路径中的类。parent ClassLoader 为 null(因为 Bootstrap Classloader 并不是由 java 实现的)。 - AppClassLoader
也是 sun.misc.Launcher 的内部类,继承自 java.net.URLClassLoader,负责加载来自在命令 java 中的 -classpath 或者 java.class.path 系统属性或者 CLASSPATH 系统属性所指定的路径中的类。其 parent ClassLoader 为 ExtClassLoader,且是我们自定义类默认的类加载器。
类加载过程
双亲委派机制:如果一个类未加载,那么必须先由其父加载器(Bootstrap Classloader 可以认为是 ExtClassLoader 父加载器)尝试加载,如果父加载器在其路径内找不到该类才由子加载器加载。可以防止核心类被外来类覆盖。
下面是结合源码,画出的利用 AppClassLoader 查找类的流程图:
Class 类
我们通常写的用 class(首字母 c 小写)定义的类,表征了 java 虚拟机里对象的类型(java 是强类型语言),但同时这些类又都是 java.lang.Class(首字母 C 大写) 的对象,通过 AppClassLoader 加载进虚拟机内存方法区。每个类都对应一个独一无二的 Class 对象,包括 Java 基本类型、void 关键字及数组(所有同一维度和类型的数组拥有同样的 Class,数组的长度不做考虑。对应 Class 的名字表示为维度和类型。比如一个整型数据的 Class 名为“[I”,字节型三维数组 Class 名为“[[[B”,两维对象数组 Class 名为“[[Ljava.lang.Object”)。得到 Class 对象的方法有三种:
MyObject foo = New MyObject();
Class c = foo.getClass();
Class c = Class.ForName("MyObject");
Class c = MyObject.class;
正文完
发表至: java
2019-06-04