一个Java文件从编码完成到最终执行,一般主要包括编译和运行两个过程
编译:将Java文件通过javac命令编译成class文件(字节码)
运行:将class文件交给JVM执行
类加载过程:JVM将字节码中类信息加载进内存,并解析生成对象的class对象的过程(JVM不是一开始就把所有的类都加载进内存中,而是只有第一次遇到某个需要运行的类时才会加载,而且只加载一次)
Java类加载的过程主要分为加载、链接、初始化三个部分,而链接又可以细分为验证、准备、解析
加载是指把class字节码文件从各个来源通过类加载器装载入内存,主要完成以下三件事:
class字节码来源:
类加载器:
什么是类加载器?
通过一个类的全限定名来获取描述此类的二进制字节流,这个动作是在JVM外部实现的,实现这个动作的代码模块称为类加载器(光碟=类,光驱=类加载器);对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在JVM中的唯一性,每一个类加载器都拥有一个独立的类名称空间(两个类的内容相同,但类加载器不同,则这两个类就是不同的)。
为什么需要自定义类加载器?
作用:保证加载进来的字节流符合JVM规范,防止造成安全错误
内容:
准备主要是为类变量分配内存,并赋予初始值(并非代码中赋予的值,而是JVM根据不同变量类型的默认初始值,但对于常量类或枚举,会赋予实例化对应的值)
解析是将常量池内的符号引用替换为直接引用的过程
符号引用:能够唯一性识别一个方法、变量、类的相关信息的字符串
直接引用:一个内存地址或者一个偏移量
如:调用地址为0x2019的hello()方法,hello为符号引用,0x2019为直接引用
初始化主要完成对类变量的初始化,也就是执行类构造器的过程
该类的父类尚未初始化,则优先初始化其父类
该类包含多个静态变量和静态代码块,则按照自上而下的顺序一次执行
双亲委派机制是指如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,当父类加载器反馈自己无法完成这个请求时,子类加载器才会尝试自己去加载完成。
好处:维护了类环境的稳定和高效运转
实现:在类加载过程中,先检查请求的类是否已经被加载过了,如果没有就调用父类的加载器加载,如果父类加载器为null,就默认使用启动类加载器作为父类加载器,如果父类加载失败,就会抛出classNotFoundException类,再调用自己的findClass方法进行加载
手机扫一扫
移动阅读更方便
你可能感兴趣的文章