由阿里巴巴笔试题看java加载顺序

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

一、阿里巴巴笔试题:

1publicclassTimplementsCloneable {2publicstaticintk = 0;3publicstaticT t1 =newT("t1");4publicstaticT t2 =newT("t2");5publicstaticinti =PRint("i");6publicstaticintn = 99;78publicintj = print("j");910{11print("构造块");12}1314static{15print("静态块");16}1718publicT(String str) {19System.out.println((++k) + ":" + str + " i=" + i + " n=" +n);20++n;21++i;22}2324publicstaticintprint(String str) {25System.out.println((++k) + ":" + str + " i=" + i + " n=" +n);26++n;27return++i;28}2930publicstaticvoidmain(String[] args) {3132}33}

二、加载过程分析:

执行main时,先加载所在类,声明静态变量,并初始化静态变量执行静态代码块(按顺序执行)

初始化到t1时,暂停类加载,先实例化,此时k=0,而i,n都未初始化,系统默认值为0

初始化j时,k自增为1,i,n为0,输出“1:j i=0 n=0”,n,i自增为1

执行代码块,输出“2:构造块 i=1 n=1”,n,i自增为2

执行构造函数,输出“3:t1 i=2 n=2”,n,i自增为3

初始化到t2时,暂停类加载,先实例化,此时k=3,i,n都还未初始化,但已自增为3

初始化j时,k自增为4,i,n未初始化为3,输出“4:j i=3 n=3”,n,i自增为4

执行代码块,输出“5:构造块 i=4 n=4”,n,i自增为5

执行构造函数,输出“6:t2 i=5 n=5”,n,i自增为6

初始化i,输出“7:i i=6 n=6”,n,i自增为7,返回自增后的i赋值给i

初始化n,赋值99

执行静态块,输出“8:静态块 i=7 n=99”,i自增为8,n自增为100

完成类加载

三、涉及知识点:

1.类加载过程:

加载某类前先加载其父类

加载某类时,先声明静态成员变量,初始化为默认值,再初始化静态成员变量执行静态代码块

初始化静态成员变量执行静态代码块时,是按顺序执行(初始化静态成员变量的本质就是静态代码块)

2.实例化过程:

对某类实例化前,先对其父类进行实例化

实例化某类时,先声明成员变量,初始化为默认值,再初始化成员变量执行代码块

初始化成员变量执行代码块时,是按顺序执行

3.在某类加载过程中调用了本类实例化过程(如new了本类对象),则会暂停类加载过程先执行实例化过程,执行完毕再回到类加载过程

4.类的主动使用与被动使用:

主动使用例子:

1):最为常用的new一个类的实例对象

2):直接调用类的静态方法。

3):操作该类或接口中声明的非编译期常量静态字段

4):反射调用一个类的方法。

5):初始化一个类的子类的时候,父类也相当于被程序主动调用了

(如果调用子类的静态变量是从父类继承过来并没有复写的,那么也就相当于只用到了父类的东东,和子类无关,

所以这个时候子类不需要进行类初始化)。

6):直接运行一个main函数入口的类。

所有的JVM实现,在首次主动使用某类的时候才会加载该类。

被动使用例子:

7):子类调用父类的静态变量,子类不会被初始化。只有父类被初始化。对于静态字段,只有直接定义这个字段的类才会被初始化.

8):通过数组定义来引用类,不会触发类的初始化,如SubClass[] sca = new SubClass[10];

9):访问类的编译期常量,不会初始化类

5.编译期常量:

写到类常量池中的类型是有限的:String和几个基本类型

String值为null时,也不会写到类常量池中

使用new String("xx")创建字符串时,得到的字符串不是类常量池中的

6.对于通过new产生一个字符串(假设为 ”china” )时,会先去常量池中查找是否已经有了 ”china” 对象,

如果没有则在常量池中创建一个此字符串对象,然后堆中再创建一个常量池中此 ”china” 对象的拷贝对象。

7.类成员变量才会有默认的初始值

byte:0(8位)

short:0(16位)

int:0(32位)

long:0L(64位)

char:\u0000(16位),代表NULL

float:0.0F(32位)

double:0.0(64位)

boolean: flase

8.局部变量声明以后,java虚拟机不会自动的为它初始化为默认值。

因此对于局部变量,必须先经过显示的初始化,才能使用它。

如果编译器确认一个局部变量在使用之前可能没有被初始化,编译器将报错。

9.数组和String字符串都不是基本数据类型,它们被当作类来处理,是引用数据类型。

引用数据类型的默认初始值都是null

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航