咱们注意到若是没有静态变量c,那么字节码文件中就不会有clinit方法
/**
* ClassLoader加载
*/
public class ClassLoaderTest {
public static void main(String[] args) {
//获取系统类加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println(systemClassLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2
//获取其上层 扩展类加载器
ClassLoader extClassLoader = systemClassLoader.getParent();
System.out.println(extClassLoader);//sun.misc.Launcher$ExtClassLoader@610455d6
//获取其上层 获取不到引导类加载器
ClassLoader bootStrapClassLoader = extClassLoader.getParent();
System.out.println(bootStrapClassLoader);//null
//对于用户自定义类来讲:使用系统类加载器进行加载
ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
System.out.println(classLoader);//sun.misc.Launcher$AppClassLoader@18b4aac2
//String 类使用引导类加载器进行加载的 -->java核心类库都是使用引导类加载器加载的
ClassLoader classLoader1 = String.class.getClassLoader();
System.out.println(classLoader1);//null
}
}
复制代码
/**
* 虚拟机自带加载器
*/
public class ClassLoaderTest1 {
public static void main(String[] args) {
System.out.println("********启动类加载器*********");
URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();
//获取BootStrapClassLoader可以加载的api路径
for (URL e:urls){
System.out.println(e.toExternalForm());
}
//从上面的路径中随意选择一个类 看看他的类加载器是什么
//Provider位于 /jdk1.8.0_171.jdk/Contents/Home/jre/lib/jsse.jar 下,引导类加载器加载它
ClassLoader classLoader = Provider.class.getClassLoader();
System.out.println(classLoader);//null
System.out.println("********拓展类加载器********");
String extDirs = System.getProperty("java.ext.dirs");
for (String path : extDirs.split(";")){
System.out.println(path);
}
//从上面的路径中随意选择一个类 看看他的类加载器是什么:拓展类加载器
ClassLoader classLoader1 = CurveDB.class.getClassLoader();
System.out.println(classLoader1);//sun.misc.Launcher$ExtClassLoader@4dc63996
}
}
复制代码
为何html
方法名称 | 描述 |
---|---|
getParent() | 返回该类加载器的超类加载器 |
loadClass(String name) | 加载名称为name的类,返回结果为java.lang.Class类的实例 |
findClass(String name) | 查找名称为name的类,返回结果为java.lang.Class类的实例 |
findLoadedClass(String name) | 查找名称为name的已经被加载过的类,返回结果为java.lang.Class类的实例 |
defineClass(String name,byte[] b,int off,int len) | 把字节数组b中的内容转换为一个Java类 ,返回结果为java.lang.Class类的实例 |
resolveClass(Class<?> c) | 链接指定的一个java类 |
拓展类加载器和系统类加载器间接继承于ClassLoader抽象类java
Java虚拟机对class文件采用的是按需加载的方式,也就是说当须要使用该类时才会将她的class文件加载到内存生成的class对象。并且加载某个类的class文件时,java虚拟机采用的是双亲微拍模式,即把请求交由父类处理,它是一种任务委派 模式git
自定义String类,可是在加载子弟敬意String类的时候回率先使用引导类加载器加载,而引导类加载器在加载过程当中会先加载jdk自带的文件(rt.jar包中的java\lang\String.class),报错信息说没有main方法就是由于加载的是rt.jar包中的String类。这样能够保证对java核心源代码的保护,这就是沙箱安全机制.github
类比举例: 咱们在读写U盘信息时能够用360沙箱,防止U盘内的病毒等对沙箱外的系统构成污染算法
JVM必须知道一个类型是有启动类加载器加载的仍是由用户类加载器加载的。若是一个类型由用户类加载器加载的,那么jvm会将这个类加载器的一个引用做为类型信息的会议部分保存在方法区中。当解析一个类型到另外一个类型的引用的时候,JVM须要保证两个类型的加载器是相同的。api
java程序对类的使用方式分为:主动使用和被动使用数组
【代码】
github.com/willShuhuan…
【笔记】
JVM_01 简介
JVM_02 类加载子系统
JVM_03 运行时数据区1- [程序计数器+虚拟机栈+本地方法栈]
JVM_04 本地方法接口
JVM_05 运行时数据区2-堆
JVM_06 运行时数据区3-方法区
JVM_07 运行时数据区4-对象的实例化内存布局与访问定位+直接内存
JVM_08 执行引擎(Execution Engine)
JVM_09 字符串常量池StringTable
JVM_10 垃圾回收1-概述+相关算法
JVM_11 垃圾回收2-垃圾回收相关概念
JVM_12 垃圾回收3-垃圾回收器安全