总结:Java中的初始化

一、类中数据初始化顺序

测试代码如下:

/**
 * 本测试主要是想确认类的初始化顺序
 * @author weiwei
 */
public class JavaClassInitSort {
	private String name = getName("属性声明"); // 静态代码块之后

	public JavaClassInitSort() { // 构造方法最后执行
		getName("构造方法");
	}

	// 初始化块
	{
		getName("初始化块"); // 属性初始化之后
	}

	static {
		getName("静态代码块"); // 最先执行
	}

	// 静态方法
	public static String getName(String str) {
		System.out.println("测试:" + str);
		return str;
	}

	public static void main(String[] args) {
		new JavaClassInitSort();
	}
}

打印结果如下:

测试:静态代码块
测试:属性声明
测试:初始化块
测试:构造方法

从中获取到哪些信息?

1、类中的属性会默认初始化。比如看源码的时候,经常莫名其妙有些东西被初始化了,其实有时候就是通过属性的方式,比如Springboot启动的时候,AbstractApplicationContext会初始化很多东西,如:

会得到Log对象
为上下文设置唯一id和显示名称
初始化BeanFactoryPostProcessors 的List集合
是否活跃标识active,1为true,0为false
是否已关闭标识closed,1为true,0为false
刷新和销毁的同步对象startupShutdownMonitor
……

追踪源码并没有看到方法中有这些操作,后来发现遗忘了一点:属性也会初始化的。

收获:属性也会初始化,Spirngboot中一些信息就是通过属性进行初始化的。

2、初始化是有顺序的分别是:静态代码块 --> 属性 --> 代码块  -->  构造方法。

收获:以后不要傻傻的只会用静态代码块进行初始化了。

二、Java中类的初始化

类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段。其中验证、准备、解析3个部分统称为连接。类加载的过程包括了加载、验证、准备、解析、初始化五个阶段。

加载、验证、准备、初始化和卸载这5个阶段的顺序时确定的,类的加载过程必须按照这种顺序按部就班的开始,而解析阶段则不一定,它在某些情况下可以在初始化阶段之后开始,这是为了支持Java语言的运行时绑定(也成为动态绑定或晚期绑定)。另外注意这里的几个阶段是按顺序开始,而不是按顺序进行或完成,因为这些阶段通常都是互相交叉地混合进行的,通常在一个阶段执行的过程中调用或激活另一个阶段。

类初始化是类加载过程的最后一个阶段,到初始化阶段,才真正开始执行类中的Java程序代码。虚拟机规范严格规定了有且只有5种情况必须立即对类进行初始化:

  • 第一种:遇到new、getstatic、putstatic、invokestatic这四条字节码指令时,如果类还没有进行过初始化,则需要先触发其初始化。生成这四条指令最常见的Java代码场景是:使用new关键字实例化对象时、读取或设置一个类的静态字段(static)时(被static修饰又被final修饰的,已在编译期把结果放入常量池的静态字段除外)、以及调用一个类的静态方法时。
  • 第二种:使用Java.lang.refect包的方法对类进行反射调用时,如果类还没有进行过初始化,则需要先触发其初始化。
  • 第三种:当初始化一个类的时候,如果发现其父类还没有进行初始化,则需要先触发其父类的初始化。
  • 第四种:当虚拟机启动时,用户需要指定一个要执行的主类,虚拟机会先执行该主类。
  • 第五种:当使用JDK1.5支持时,如果一个java.langl.incoke.MethodHandle实例最后的解析结果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,则需要先触发其初始化。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值