初始化块就是在类的内部直接用{}括起来的一段代码(注意这段代码必须在方法外,方法内的是代码块)。初始化块用于对象或类的初始化。
原则上讲,一个类可以有多个初始化块,按照定义的先后顺序依次执行。但实际上根本没必要定义多个初始化块。
初始化块内部可以放任何可执行性语句,它和构造器都是用于初始化对象。只是构造器是一个方法,根据传入参数的不同,不同对象的构造器执行结果会不同。但初始化块不接受任何参数,所以,初始化块执行的内容相对死板。
实例初始化块和类初始化块
初始化块作为类的第四个成员,它的修饰符只有一个static。
如果在{}之前加上static修饰符,就表明这是类初始化块。
如果没有修饰符,就是实例初始化块。
实例初始化块与对象相关,会在对象初始化阶段执行代码,帮助对象初始化。
而类初始化块与类相关,在类加载阶段就会执行,帮助类的初始化。
由于类的初始化早于对象初始化,所以类初始化块一定会先于实例初始化块执行。
类初始化块也是类成员,要遵循类成员不能访问实例成员的原则。这很好理解,凡是和类相关的成员,都不能出现和对象相关的代码,否则系统根本不知道选择哪个对象。
# 初始化块的执行顺序 **实例初始化块和声明实例变量指定的默认值的优先级是一样的**,谁先执行看代码定义的顺序。 **它们两者都先于构造器部分代码执行**。 **而类初始化块与类变量指定默认值优先级是一样的**,由于类的初始化一定先于对象。所以**类初始化块的执行一定先于实例初始化块**。
初始化块的作用
由于不管调用哪一个构造器,初始化块的代码一定先被执行。
所以,可以把所有构造器都有的公共代码放到初始胡块中。
# 初始化块与继承 由于子类在初始化时,会先初始化父类的部分。所以,实际是从最顶层父类开始初始化的。
如果是第一次加载子类,那么应该先进行类的初始化。所以会溯源到最顶层父类的类初始化块和声明类变量的默认值,依次执行到子类本身的类初始化块和声明类变量的默认值。
在整个类加载完成,类相关初始化代码执行完成后,才进行子类实例的初始化。
每个子类初始化时,最先执行的一定是Object类的构造器(Object没有实例初始化块和实例变量指定默认值代码),紧接着是下一个父类的实例变量指定默认值和初始化块、构造器,最后才是子类的实例变量指定默认值和初始化块,构造器。