千锋教育-做有情怀、有良心、有品质的职业教育机构

400-811-9990
手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

上海
  • 北京
  • 郑州
  • 武汉
  • 成都
  • 西安
  • 沈阳
  • 广州
  • 南京
  • 深圳
  • 大连
  • 青岛
  • 杭州
  • 重庆
当前位置:大连千锋IT培训  >  技术干货  >  经典面试题:static加载机制你知道吗?

经典面试题:static加载机制你知道吗?

来源:千锋教育
发布人:bjq
时间: 2023-03-09 16:00:36

  经典面试题: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

什么是Java循环?

2023-03-30

switch语句的case和default有顺序吗?

2023-03-30

SpringBoot中使用redis 新手入门

2023-03-29

最新文章NEW

10分钟学会阿里OSS对象存储

2023-03-07

没有弹性盒,如何玩转移动端?

2023-02-13

浮动布局详解

2023-02-10

相关推荐HOT

更多>>

快速通道 更多>>

最新开班信息 更多>>

网友热搜 更多>>