目标
- 从阿里巴巴笔试题看Java加载顺序
static
- 公有属性,可以由类名称直接访问
- 静态方法,可以由类名称直接调用方法
- 静态方法或属性,可以在对象实例化之前就调用
阿里巴巴笔试题
|
|
运行结果如下:
|
|
关键点
关键点:(代码注释上已给出)
- 先初始化静态成员k=0,k = 0;t1 = new Test1(“t1”); t2 = new Test1(“t2”);i = print(“i”); int n = 99;,所以应该是先k=0,
- 接着初始化t1,t1的初始化是调用构造方法,所以先初始化对象,而初始化对象就像上面的说明先初始化实例成员j和代码块print(“构造块”);,此时k=0;++k后k=1,i和n的初始值都为0,因此初始化j的时候打印”1:j i=0 n=0”,接着++i;++n;后i和n的值都为1,初始化代码块print(“构造块”)的时候打印”2:构造块 i=1 n=1”;
- 后面的静态成员和实例成员的初始化跟上面步骤1,2类似,自己推导一下就能得到结果;
总结
几大原则
一、静态成员变量(static)
- 静态成员变量为类变量,所有对象共享同一内存空间
- 静态成员变量的声明和定义仅在首次加载时执行一次
- 手机加载类时首先对所有静态成员变量根据类型默认赋初值,然后再对有右值的赋右值
二、静态初始块
- 多个静态成员变量与静态初始化块参照出现顺序先后执行
三、动态成员变量
- 动态成员变量定义,在每次实例化对象时,在构造函数之前执行
四、动态初始化块
- 动态初始化块的执行是在每次实例化对象时,在构造函数之前执行
- 多个动态成员变量与动态初始化块参照出现顺序先后执行
总结:总的来说,在不涉及继承的前提下,当首次加载类时,按照如下顺序执行
- 按照出现顺序先后执行静态成员变量定义与静态初始化块
- 按照出现顺序先后执行动态成员变量定义与动态初始化块
- 执行构造函数
- 再次实例化对象时只执行第2、3步即可
五、当涉及到继承时,按如下顺序执行
- 执行父类的静态成员变量定义与静态初始化块,执行子类的静态成员变量定义与静态初始化块
- 执行父类的非静态成员变量定义与动态初始化块,执行父类构造方法
- 执行子类的非静态成员变量定义与动态初始化块,执行子类构造方法
另:父类构造方法中用到的方法如果已被子类重写,那么在构造子类对象时在调用父类构造函数中使用子类重写的方法。
More info: 更多