本文将通过一个具体的Bean实例一步步解析jvm中的类加载过程,以下是需要用到的类定义。
//bean的定义
package com.beanload.test;
public class BeanLoadTestSupper{
static {
System.out.println("BeanLoadTestSupper init");
}
public static int value = 123;
}
public class BeanLoadTestSub extends BeanLoadTest {
public static List<String> testLists = new LinkedList<String>();
public static String TEST_STR="test str";
public static String getTestStr(){
return TEST_STR;
}
static {
System.out.println("BeanLoadTestSub init");
}
}
类生命周期包括以下5个过程
加载,验证,准备,解析,初始化,卸载
加载实现的主要功能有以下几点:
1)通过一个类的全限定名来获取定义此类的二进制字节流。
2)将这个字节流所代表的静态存储结构转换为方法区的运行时数据结构
3)在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。
假如BeanLoadTestSub.java编译后的class文件存放在com.beanload.test目录下。
以下过程解析 BeanLoadTestSub test = new BeanLoadTestSubTest()时虚拟机加载类的过程。
触发类初始化的几种情况
(在此之前需要完成类的加载,验证,准备,解析等过程)
- 遇到了new,getstatic,putstatic,invokestatic这4条字节码指令时,如果类没有初始化,则需要先触发初始化。
a) new–>使用new关键字实例化对象b)读取或者设置一个类的静态字段(被final修饰,已在编译期把结果放入常量池的静态字段除外)BeanLoadTestSub test = new BeanLoadTestSubTest()
c)调用类的静态方法时String testStr=BeanLoadTestSubTest.testStr;
String testStr=BeanLoadTestSubTest.getTestStr();