经典面试题:static加载机制你知道吗?
经典面试题:static加载机制你知道吗?
static在Java中是一个很常见的关键字,同时它也是面试时的一个高频考点。那么在Java类中,static的加载机制到底是怎样的呢?接下来百泽老师就来带大家弄明白这个问题。
一. 类加载机制
JVM在首次使用某个类时,会通过 classpath 来查找该类的.class文件。然后将.class文件中对类的描述信息加载到内存中进行保存,如:包名、类名、父类、属性、方法、构造方法......一个类的加载过程大致如下:
加载时机
创建对象
创建子类对象
访问静态属性
调用静态方法
主动加载:Class.forName(“全限定名”)
二. static 特点
被static关键字修饰的类或方法、成员等具有如下特点:
静态方法允许直接访问静态成员;
静态方法不能直接访问非静态成员;
静态方法中不允许使用this或是super关键字;
静态方法可以继承,不能重写、没有多态。
三. 经典面试题
接着我们再来看看关于static的一个经典面试题,代码案例如下:
public class Test {
public static int k = 0;
public static Test t1 = new Test("t1");
public static Test t2 = new Test("t2");
public static int i = print("i");
public static int n = 99;
private int a = 0;
public int j = print("j");
{
print("构造代码块");
}
static{
print("静态构造代码块");
}
public Test(String str){
System.out.println((++k)+":"+str+" i="+i+" n="+n);
++i;
++n;
}
public static int print(String str){
System.out.println((++k)+":"+str+" i="+i+" n="+n);
++n;
return ++i;
}
public static void main(String[] args) {
}
}
这是一道关于static加载执行顺序的经典面试题,根据代码观察执行结果,接下来我们就来分析一下上述代码的执行结果是什么。
在执行 main 方法,也就是程序主入口的时候,首先会加载所在的类,声明静态变量,初始化静态属性,执行静态代码块(按照顺序执行),所以首先加载的是:
public static int k = 0;
2. 其次加载:
public static Test t1 = new Test("t1");
3. 而加载到实例化 t1 对象时,类的加载会暂停,然后创建 Test 的实例对象。在创建 Test 对象时则会先加载属性再执行代码块,最后执行构造方法,所以先执行的会是实例属性。
private int a = 0;
public int j = print("j");
public static int print(String str){
System.out.println((++k)+":"+str+" i="+i+" n="+n);
++n;
return ++i;
}
4. 因加载类的过程中,会对定义的静态字段在方法区中分别分配空间,并赋予初始化值,所以 i 和 n 的值都为0,因此第一个打印语句是:
1:j i=0 n=0
5. 实例属性加载完毕后,则进行构造代码块的加载:
{
print("构造代码块");
}
public static int print(String str){
System.out.println((++k)+":"+str+" i="+i+" n="+n);
++n;
return ++i;
}
6. 因为第一次调用时已经对 k 、i 、n 的值进行了自加,因此第二个打印语句是:
2:构造代码块 i=1 n=1
7. 实例化对象的最后一步,则是执行构造方法:
public static Test t1 = new Test("t1");
public Test(String str){
System.out.println((++k)+":"+str+" i="+i+" n="+n);
++i;
++n;
}
8. 因此第三个打印语句是:
3:t1 i=2 n=2
9. t1 对象创建完毕后,类加载则继续执行,因此下一步则是:
public static Test t2 = new Test("t2");
10. 按照前面实例化 t1 的执行机制,因此接下来的打印的几句则是:
4:j i=3 n=3
5:构造代码块 i=4 n=4
6:t2 i=5 n=5
11. 实例化完 t2 对象后,继续进行类加载,因此下一步加载静态属性 i 的赋值:
public static int i = print("i");
public static int print(String str){
System.out.println((++k)+":"+str+" i="+i+" n="+n);
++n;
return ++i;
}
12. 因此下一步打印结果为:
7:i i=6 n=6
13. 加载完最后一个静态属性 n= 99 后,则加载静态构造代码块:
public static int n = 99;
static{
print("静态构造代码块");
}
public static int print(String str){
System.out.println((++k)+":"+str+" i="+i+" n="+n);
++n;
return ++i;
}
13. 因此最后会打印:
8:静态构造代码块 i=7 n=99
14. 所以整体的执行结果会是:
1:j i=0 n=0
2:构造代码块 i=1 n=1
3:t1 i=2 n=2
4:j i=3 n=3
5:构造代码块 i=4 n=4
6:t2 i=5 n=5
7:i i=6 n=6
8:静态构造代码块 i=7 n=99
猜你喜欢LIKE
相关推荐HOT
更多>>算法评测标准---空间复杂度是什么?
算法评测标准---空间复杂度是什么?空间复杂度是什么?一. 空间复杂度的概念,复杂度(Space Complexity),是对一个算法在运行过程中临时占用存...详情>>
2023-03-23 20:15:04怎么用css画三角形?
怎么用css画三角形?border这里的像素值 和 border-left这里的像素值可以是不一样的,也可以是一样的,根据三角形的形状来进行具体设置值即可,要...详情>>
2023-03-23 15:27:16Maven集成 tomcat插件及使用教程
在实际的项目开发中,特别是分布式项目,往往有N多个子项目需要同时启动测试。这样多个项目引用tomcat插件,配置不同的端口,就可以同时启动N个...详情>>
2023-02-23 14:44:00扫盲CSS中常见的单位
Px是pixel的简写, 被称之为像素单位, px可以在计算机屏幕上,能达到预期的效果,在打印机和其它的高分辨率设备上,它又能取得所希望的效果, 一...详情>>
2023-02-16 13:47:00热门推荐
如何配置Java环境变量?有方法吗?
沸java变量的作用域是什么?
热什么是Java循环?
热switch语句的case和default有顺序吗?
新SpringBoot中使用redis 新手入门
vue的watch和computed的区别以及特点是什么?
算法评测标准---空间复杂度是什么?
Spring整合Junit框架是什么?
break和continue必须要在循环中使用吗?
怎么用css画三角形?
手把手教你搭建Oauth2授权服务!
为什么不能用break?
什么是foreach循环?它有哪些优点和局限性?
react生命周期?16版本删除了什么钩子函数?为什么删除?