虚拟机类加载机制
-------------------------
虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验,转换、解析
最终形成虚拟机可以直接使用的Java类型,这就是虚拟机的类加载机制
两个约定
---------------------------
1、每个Class文件都有可能代表着Java语言中的一个类或者接口
类和接口需要分开描述的场景会特别说明
2、这里所说的‘Class文件’并非指存在与具体磁盘中的某个文件
这里所属的class文件指的是一串二进制字节流,无论以何种
形式存在都可以
类加载时机
------------------------------------
类加载的生命周期:
加载(Loading)
验证(Verification)
准备(Preparation)
解析(Resolution)
初始化(Initialization)
调用:
1、当遇到new 、getstatic 、putstatic 、invokestatic四条指令时,如果类没有进行初始化
则需要首先触发其初始化
2、使用java.lang.reflect包的方法对类进行反射调用,如果没有进行初始化,则出发初始化
3、当初始化一个类的时候,发现父类没有进行初始化,则先出发父类初始化
4、当虚拟机启动的时候,用户需要指定也给要执行的主类,虚拟机会初始化这个类
注意:以上四种行为被称为主动引用,除此之外所有引用类的方式,都不会触发初始化,被称为被动引用
不会触发的几种情况:
1、通过子类调用父类的静态变量,不会触发子类的初始化
2、通过数组定义来引用类,不会触发此类的初始化,这里由虚拟机自动生成
一个Object的子类来触发
3、调用常量不会进行初始化,常量在编译的时候会被存入常量池,因此不会触发类的初始化
场景:1、new关键字实例化对象(new)
2、读取或设置一个类的静态字段(getstatic,putstatic)
3、调用一个类的静态方法(invokestatic)
使用(Using)
卸载(Unloading)
其中,验证、准备、解析这三个阶段统称为连接(Linking),
注意:加载、验证、准备、初始化、和卸载这几个过程的顺序是确定的
而解析的过程则不一定
类加载过程
---------------------------
1、加载
1、通过一个类的全限定名来获取定义此类的二进制字节流
类加载的来源:
1、这里不一定都是从Class文件中读取,还可以从zip,jar,ear,war包中读取
2、从网络中读取,这种场景最经典的应用就是applet
3、运行时计算生成,这种场景使用最多的就是动态代理技术,在java.lang.reflect.Proxy
4、由其他文件生成
5、从数据库读取,这种场景相对少见,有些中间件服务器可以选择把程序安装到
数据库中来完成代码在集群间的分发
2、将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
3、在java堆中生成一个代表这个类的java.lang.Class对象,作为方法区这些数据的访问入口
2、验证
验证是连接的第一步,这一步阶段的目的是为了确保Class文件的字节流中包含的信息符合当前