【java】初始化顺序

1、静态代码块并不一定初始化在静态成员前,两者顺序关系与代码的顺序有关,依据如下实验

/**
 * 测试类的初始化顺序
 * @author 神奇女侠
 *
 */

public class MyTest {

	
	//静态成员
	public static MyTest t=new MyTest();
	
	//静态代码块
	static
	{
		System.out.println("这里是MyTest类的静态代码块");
	}
	
	//构造函数
	public MyTest()
	{
		System.out.println("构造函数被执行");
	}
	
	//主函数
	public static void main(String[] args)
	{
		
	}

}

执行结果:

构造函数被执行
这里是MyTest类的静态代码块

 

/**
 * 测试类的初始化顺序
 * @author 神奇女侠
 *
 */

public class MyTest {
	//静态代码块
	static
	{
		System.out.println("这里是MyTest类的静态代码块");
	}
		
	//静态成员
	public static MyTest t=new MyTest();
	
	//构造函数
	public MyTest()
	{
		System.out.println("构造函数被执行");
	}
	
	//主函数
	public static void main(String[] args)
	{
		
	}
}

执行结果:

这里是MyTest类的静态代码块
构造函数被执行

2、内部类的静态代码块与静态成员的初始化顺序也与代码中的顺序有关

public class MyTest {
	//静态代码块
	static
	{
		System.out.println("这里是MyTest类的静态代码块");
	}
		
	//静态成员
	//public static MyTest t=new MyTest();
	
	//构造函数
	public MyTest()
	{
		System.out.println("构造函数被执行");
	}
	
	//内部类
	public static class Inner
	{
		//内部类的静态代码块
		static
		{
			System.out.println("这里是Inner类的静态代码块");
		}
			
		//静态成员
		public static MyTest t=new MyTest();
		
		public static void Method()
		{
			System.out.println("Method()被执行");
		}
	}
	
	//主函数
	public static void main(String[] args)
	{
		MyTest.Inner.Method();
	}
}

执行结果:

这里是MyTest类的静态代码块
这里是Inner类的静态代码块
构造函数被执行
Method()被执行

public class MyTest {
	//静态代码块
	static
	{
		System.out.println("这里是MyTest类的静态代码块");
	}
		
	//静态成员
	//public static MyTest t=new MyTest();
	
	//构造函数
	public MyTest()
	{
		System.out.println("构造函数被执行");
	}
	
	//内部类
	public static class Inner
	{
		
		//静态成员
		public static MyTest t=new MyTest();
		
		//内部类的静态代码块
		static
		{
			System.out.println("这里是Inner类的静态代码块");
		}
					
		
		public static void Method()
		{
			System.out.println("Method()被执行");
		}
	}
	
	//主函数
	public static void main(String[] args)
	{
		MyTest.Inner.Method();
	}
}

这里是MyTest类的静态代码块
构造函数被执行
这里是Inner类的静态代码块
Method()被执行

3、类的使用需经过加载(将二进制文件,即.class文件加载进内存),链接,初始化。静态代码块的执行与静态成员的初始化都在类的初始化时期;也就是说,类只有被使用时才会完成初始化。

分析:MyTest的静态代码块始终首先被执行,是因为jvm使用了MyTest内的main方法。所以MyTest在执行初的时候就完成了加载,链接,初始化三步。

而Inner可以理解为是MyTest的静态成员,应该在一开始就完成了初始化,但是Inner内的静态代码块却没有在MyTest的静态成员初始化的时候执行,说明这时的Inner只是完成了加载,链接两步。直到调用了Inner内的Method方法,Inner的初始化才被完成。

4、只有类完成初始化之后(加载,链接,初始化),才可以new对象。new对象的初始化顺序为:构造代码块,成员变量初始化,构造函数(先父后子)

 

总结:类的初始化与对象的初始化是不一样的,也就可以理解为什么静态的只会执行一次,而非静态new多少次就执行多少次。因为静态的初始化是在类本身的初始化时期进行的,与对象的初始化不同。

 

引用一下别人的总结:

顺序是:父类静态属性->父类静态代码块->子类静态变量->子类静态代码块->父类非静态变量->父类非静态代码块->父类构造函数->子类非静态变量->子类非静态代码块->子类构造函数

这样的加载顺序不是绝对的 因为静态变量和静态代码块跟声明顺序有关。

对于如果静态代码块中调用静态变量,那么静态变量必须在静态代码块前面声明;如果静态代码块中没有调用静态变量,那么就跟顺序有关了,谁先声明谁先被加载。说白了还是顺序加载,之所以会出现“如果静态代码块中调用静态变量,那么静态变量必须在静态代码块前面声明”,是因为变量是声明,所以出现编译错误。

应用到内部类中 静态变量和静态代码块跟声明顺序有关。 这样就可以解释你的问题了。内部类也是类。

测试所用jdk版本1.8.0_20

类静态块-类静态属性这个跟顺序有关系 如果类静态属性在类静态代码块之前 那么类静态属性先初始化

参考:https://www.oschina.net/question/2273217_217864

          http://www.cnblogs.com/yahokuma/p/3668138.html

 

发表仅为记录学习过程,如有错误,请多指教

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕业设计,基于SpringBoot+Vue+MySQL开发的影城管理系统,源码+数据库+论文答辩+毕业论文+视频演示 随着现在网络的快速发展,网上管理系统也逐渐快速发展起来,网上管理模式很快融入到了许多生活之中,随之就产生了“小徐影城管理系统”,这样就让小徐影城管理系统更加方便简单。 对于本小徐影城管理系统的设计来说,系统开发主要是采用java语言技术,在整个系统的设计中应用MySQL数据库来完成数据存储,具体根据小徐影城管理系统的现状来进行开发的,具体根据现实的需求来实现小徐影城管理系统网络化的管理,各类信息有序地进行存储,进入小徐影城管理系统页面之后,方可开始操作主控界面,主要功能包括管理员:首页、个人中心、用户管理、电影类型管理、放映厅管理、电影信息管理、购票统计管理、系统管理、订单管理,用户前台;首页、电影信息、电影资讯、个人中心、后台管理、在线客服等功能。 本论文主要讲述了小徐影城管理系统开发背景,该系统它主要是对需求分析和功能需求做了介绍,并且对系统做了详细的测试和总结。具体从业务流程、数据库设计和系统结构等多方面的问题。望能利用先进的计算机技术和网络技术来改变目前的小徐影城管理系统状况,提高管理效率。 关键词:小徐影城管理系统;Spring Boot框架,MySQL数据库
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值