类(文件 Hello.class)-->JVM 加载到内存的过程。
目录
1.类加载的流程
流程
-
加载
-
作用: Car.class --->内存
-
何时:
-
new Car()
-
Class.forName("包名.类");
-
-
怎么加载 ClassLoader(类加载器)
-
Bootstrap
-
Ext
-
App
-
(app-->继承--->ext-->继承-->-bootstrap )
双亲委托(派)机制 java.lang.String
-
-
Car.class--->加载(App)-->Ext(检查)-->Bootstrap
-
/* * 类加载器之间关系 */ System.out.println(clazz.getClassLoader()); System.out.println(clazz.getClassLoader().getParent()); System.out.println(clazz.getClassLoader().getParent().getParent());
-
创建一个Class对象
String s = "abc";--->String.class
如何获取Class对象
类.class
对象.getClass()
Class.forName("包名.类"); --->Class<?>
/* * 不同类加载器加载的内容 * 为什么使用新jar包需要点击“Buider Path” ? */ System.out.println("app:" + System.getProperty("java.class.path")); System.out.println("ext:" + System.getProperty("java.ext.dirs")); System.out.println("----bootstrap---"); String[] str = System.getProperty("sun.boot.class.path").split(";"); for (String s : str) { System.out.println(s); }
-
-
链接
- 验证:1.目的是为了确保 Class文件的字节流中包含的信息符合当前虚拟机的要求且不
会危害虚拟机自身的安全。
2.包括:文件格式验证(是否以魔数oxcafebabe开头)、元数据验证、字节码验证和
符号引用验证 - 准备
-
static 分配内存空间,static-->方法区,初始化
class A{ static int x = 3; --->分配static内存 x=0; }
-
- 解析:将符号引用转化为直接引用的过程
- 验证:1.目的是为了确保 Class文件的字节流中包含的信息符合当前虚拟机的要求且不
-
初始化: 类初始化
- x = 3;
- 使用
- 卸载
2.类加载器
类加载器:实现通过一个类的全限定名来获取描述此类的二进制字节流的动作的代码模板就叫做类加载器。
自顶向下分别为启动类加载器(Bootstrap ClassLoader),扩展类加载器(Extension ClassLoader),应用程序类加载器(Application ClassLoader),
自定义类加载器。
3.双亲委派模式
双亲委派模式:以三个层级的类加载器来解释双亲委派模式的工作原理:
当应用程序类加载器收到了类加载的请求,它会查看自己的缓存中已经加载的类,如果目标类没有在缓存中,就会委派上级扩展类加载器。扩展类加载器也会查看自己的缓存中已经加载的类,如果目标类没有在缓存中,就会委派上级启动类加载器。启动类加载器在JAVA_HOME/jre/lib下寻找目标类,如果没有。扩展类加载器会调用自己的findClass方法,在 JAVA_HOME/jre/lib/ext下寻找 目标类。如果没有,会回到应用程序类加载器,应用程序类加载器会调用它自己的findClass方法,在classpath(即类路径)下查找目标类。此时就会找到目标类,就会处理目标类的类加载请求。
优点:
1. 通过这种带有优先级层次关系的机制可以避免类的重复加载。
2. 双亲委派模式考虑到了安全因素,可以防止核心API库被随意篡改。