类的生命周期从类被加载,连接和初始化开始,到类被卸载结束。只有当类处与生命周期中,Java才可以使用它,比如调用类的静态属性和方法,或者创建类的实例。
类的加载,连接和初始化
当java程序运行某个类时,Java虚拟机会保证这个类已经被加载,连接,初始化。
类的加载
类加载器不需要等到某个类被“首次主动使用”时再加载它,Java虚拟机会预先加载它,如果在预先加载中文件缺失或者存在错误,类加载器必须等到程序首次主动使用该类时才报告错误。
类的连接
类的连接包括验证,准备和解析
验证:确保被加载类的正确性。
准备:为类的静态变量分配内存,并将其初始化为默认值。
解析:把类中的符号引用转换为直接引用。
类的初始化
给类的静态变量赋予正确的初始值。
初始化一个类有以下几个步骤:
1.假如这个类没有被加载连接,那就先进行加载和连接。
2.假如类存在直接的父类,并且这个父类还没有初始化,先初始化直接的父类。
3.假如类中存在初始化语句,那就依次执行这些初始化语句。
例子:
父类:
static int a;
static {
System.out.println("父类静态代码块");
}
{
System.out.println("父类构造代码块");
}
public FuLei() {
System.out.println("父类无参构造");
}
子类:
static int b;
static {
System.out.println("子类静态代码块");
}
{
System.out.println("子类构造代码块");
}
public ZiLei() {
System.out.println("子类无参构造");
}
测试类:
public static void main(String[] args) {
System.out.println("3.开始测试");
ZiLei zilei = new ZiLei();
System.out.println(ZiLei.b); //我的子类类名就叫ZiLei,但不建议这样取名哈,这个是打印子类的b
}
static {
System.out.println("测试类静态代码块");
}
运行结果:
测试类静态代码块
开始测试
父类静态代码块
子类静态代码块
父类构造代码块
父类无参构造
子类构造代码块
子类无参构造
0
执行顺序:静态代码块→构造代码块→构造方法→普通代码块。
有继承会先加载父类
类的卸载
由Java虚拟机自带的类加载器所加载的类,在虚拟机的生命周期中,始终不会被卸载,Java虚拟机自带的类加载器包括根类加载器、扩展类加载器和系统类加载器,Java虚拟机本身会始终引用这些类加载器,而这些类加载器则会始终引用它们所加载的类的Class对象,因此这些Class对象始终是可触及的。
由用户自定义的类加载器加载的类是可以被卸载的。