类加载器
第一个类加载器
类加载器的加载过程,加载过程是分成不同的层次来加载,不同的类加载器来加载不同的class,最顶层的是Bootstrap,他是来加载lib里jdk最核心的内容。
第二个类加载器
这个是Extension加载器扩展类,加载扩展包里的各种各样文件,这些扩展包在jdk安装目录jre/lib/ext下的jar
第三个类加载器
这个就是平时用的加载器application,它用于加载classpath指定内容
第四个类加载器
这个就是自定义加载器ClassLoader,加载自己自定义的加载器
双亲委派
-
父加载器
父加载器不是“类加载器的加载器”。也不是“类加载器的父类加载器”
双亲委派是一个孩子向父亲方向,然后父亲向孩子方向的双亲委派过程
自定义类加载器
-
继承ClassLoader
-
重写模板方法findClass(调用defineClass)
-
自定义类加载器加载加密的class
防止反编译
防止篡改
-
类加载器的范围
sun.boot.class.path
- Bootstrap ClassLoader加载路径
java.ext.dirs
- ExtensionClassLoader加载路径
java.class.path
- AppClassLoader加载路径
class cycle
Loading
是把一个class文件load内存装到内存里去,它本来是class文件上的一个二进制,一个一个的字节,装完之后就是Linking
Linking分为三步
- verification:就是验证文件是否符合jvm的规定,格式不对我就不会在进行下一步操作
- Preparation:给静态成员变量赋默认值,在三步里给这些值初始化
- Resolution:叫解析,将类,方法,属性等符号引用解析为直接引用,将常量池的各种符号引用解析为指针,偏移量等内存地址的直接引用
自定义类加载器
-
继承ClassLoader
-
重写模板方法findClass
- 调用defineClass
-
自定义类加载器加载自加密的class
- 防止反编译
- 防止串改
(懒加载)
-
严格讲应该叫lazyInitializing
-
JVM规范并没有规定何时加载
-
但是严格规定了什么时候必须初始化
new getstatic putstatic invokestatic指令,访问final变量除外
java.lang.reflect对类进行反射调用时
初始化子类的时候,父类首先初始化
虚拟机启动时,被执行的主类必须初始化
动态语言支持java.lang.invoke.MethodHandle解析的结果为REF_getstatic
REF_putstatic REF_invokestatic的方法句柄时,该类必须初始化
混合模式
默认的混合模式:混合使用解释器+热点代码编译