Java中对类进行初始化(主动引用,被动引用)

本文探讨了Java中类初始化的5种主动引用情况,包括new、getstatic、putstatic、invokestatic指令,反射调用,父类及主类初始化,以及JDK1.7的动态语言支持。同时,列举了3个被动引用的例子,如通过子类引用父类静态字段、数组定义引用和调用常量,这些都不会触发类的初始化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个类的整个生命周期包括:加载,验证,准备,解析,初始化,使用,卸载

这里主要介绍一下必须对类进行“初始化”的5种情况

1、遇到new,getstatic,putstatic,invokestatic这四条字节码指令时;

2、对类进行反射调用时,如果类没有进行过初始化,则需先触发其初始化;

3、当初始化一个类时,其父类还没初始化,则需先触发其父类初始化;(PS:当一个接口在初始化时,并不要求其父接口全部都已初始化,只有在真正使用到父接口的时候才会初始化)

4、当虚拟机启动时,会先初始化主类;

5、当使用JDK1.7的动态语言支持时,如果一个java.lang.invoke.MethodHandle实例最后的解析结果  REF_getStatic, REF_gpuStatic,REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,则需要先触发其初始化。

以上五种场景称为对类进行主动引用,除此之外,所有引用类的方式都不会触发初始化,称为被动引用

下面介绍几个被动引用的例子

1、通过子类引用父类的静态字段

class FatherClass{
	static{
		System.out.println("FatherClass init");
	}
	public static int value = 123;
}
class SonClass extends FatherClass{
	static{
		System.out.println("SonClass init");
	}
}

public class Demo{
	public static void main(String[] args){
		System.out.println(SonClass.value);
	}
}

运行结果

可以看到,并没有输出SonClass init,子类没有被初始化,对于静态字段,只有直接定义这个字段的类才会被初始化

2、通过数组定义来引用类

class FatherClass{
	static{
		System.out.println("FatherClass init");
	}
	public static int value = 123;
}

public class Demo{
	public static void main(String[] args){
		FatherClass[] ar = new FatherClass[10];
	}
}

该程序不会有任何输出,没有输出FatherClass init,说明没有触发FatherClass初始化

3、调用常量时

class ConstClass{
	static{
		System.out.println("ConstClass init");
	}
	public static final String STR = "hello";
}

public class Demo{
	public static void main(String[] args){
		System.out.println(ConstClass.STR);
	}
}

运行结果

从结果中可以看出,并没有出现ConstClass init,说明定义常量的类没有被初始化,常量在编译阶段会存入调用类的常量池中,本质上并没有直接引用到定义常量的类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值