1.初始化块
初始化块,分为一般初始化块和静态初始化块,前者在创建对象时调用,后者在加载类时初始化静态成员
(一般初始化块也可以初始化静态变量只是得在创建对象时候了,而静态初始化不能初始化实例变量,因为没有this)
2.执行顺序
父类静态成员开辟空间->父类静态初始化块->子类静态成员开辟空间->子类静态初始化块(即加载类的时候)
->父类实例全局变量->父类初始化块->父类构造方法->子类实例全局变量->子类初始化块->子类构造方法
3.初始化原理
变量初始化有三个过程,一个是定义时初始化,一个是初始化块初始化,还有一个是构造方法初始化,
前两个通过我反汇编,发现实际上前两者会跟据出现顺序加到构造方法上一起初始化,
所以一般初始化块要写在定义初始化(其实只是定义没初始化的话影响并不大)后面,不然初始化块初始化的值会被定义初始化的值覆盖掉。
如下面代码:name显示按照初始化块和定义初始化的顺序,先被初始化为"初始化块初始化name",然后被初始化为 "定义时初始化name",前两者会根据
出现循序不同确定先执行那个,但最后都会执行构造方法的初始化,即赋值为“构造器初始化”。public class BB{ public static void main(String[] agrs){ A a = new A(); } } class A{ { name = "初始化块初始化name"; //System.out.println(name); 非法的向前引用 System.out.println(this.name); } String name = "定义时初始化name"; public A(){ System.out.println(name ); name = “构造器初始化” System.out.println(name ); } } //输出结果: 初始化块初始化name // 定义时初始化name // 构造器初始化
4.碰到的问题
初始化块在属性定义上面的时候能赋值 但不能输出,一输出就会出现非法的向前引用
但加上this之后就不会报错 这让我不理解,网上查到oracle官方的说明:
只有在全部满足以下4点的情况下,成员变量的声明才必须在使用之前,否则顺序无关
•使用出现在C的实例/静态变量初始化,或者C的实例/静态初始化块中 (System.out.println(name); 出现在非静态初始化块中,满足)
•使用不在赋值表达式左边 (输出name,也即不在赋值表达式左边,满足)
•使用是通过简单名称 (name不带类名,满足)
•C是包含该使用的直接类/接口 (C即为代码中A,满足)