一道面试题:静态代码块的执行顺序

Posted zzfree

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一道面试题:静态代码块的执行顺序相关的知识,希望对你有一定的参考价值。

先来看一道最常见的面试题:静态代码块的执行顺序?

看一下实际运行:

class A{
    static {
        System.out.println("A的静态代码块");
    }
        {
        System.out.println("A的构造代码块/非静态代码块");
    }
    public A() {
        System.out.println("A的构造函数");
    }
}
class B extends A{
     static {
            System.out.println("B的静态代码块");
        }
            {
            System.out.println("B的构造代码块/非静态代码块");
        }
        public B() {
            System.out.println("B的构造函数");
        }    
}
//测试程序执行
public
static void main(String[] args) { System.out.println("==== main开始执行 ===="); new B(); System.out.println("==== B已经被创建 ====="); }

答案是:

==== main开始执行 ====
A的静态代码块
B的静态代码块
A的构造代码块/非静态代码块
A的构造函数
B的构造代码块/非静态代码块
B的构造函数
==== B已经被创建 =====

好了,现在开始小白的问答环节:

 

Q1:不是说,静态块里的内容在类被加载的时候就执行,存在方法区(静态区)中,那为什么是先有main开始执行的语句打印呢?

A1:首先要明白,什么叫类加载:类加载就是把需要的类的代码加载到内存中,且在此类首次使用时静态代码块被加载执行,也就是说静态代码块只执行一次

什么时候有类加载:1.创建实例   2.调用该类的静态方法时(静态块代码优先于静态函数执行) 3.使用该类的非常量静态字段 4.使用反射方法时  5.初始化该类的子类

 

Q2:上面说存在方法区中,那么方法区是什么?Java内存布局里没有方法区呀?

A2:《Java虚拟机规范》只是规定了有方法区这个概念,在HotSpot上使用永久代来实现方法区。而到了JDK8,永久代被元空间(MetaSpace)替换,其他内容由永久代移入元空间,比如说

类元信息,字段,静态属性,方法,常量等,除了字符串常量,它被移入了堆内存

 

Q3:什么是构造代码块呢?

A3:构造代码块:初始化所有对象。属于对象的,在new 的时候才会执行,而构造函数是new的时候,调用了构造方法,所以构造代码块会先一步

 

Q4:为什么我构造方法写成了 public void A(){} 就不可以了呢?构造方法为什么不可以有返回值?

A4:构造方法在Java语言规范里面叫 “Constructor” ,并不是一个成员方法(成员方法叫 Method),其实应该叫 “构造器”更合适。

   构造方法在类创建的期间(new)被执行用于对象初始化的,只有在构造方法执行完了,类的创建才算是完成了。

  既然是用于初始化对象的,那么没有返回值是很正常的事情了,虚拟机规范中也是这么形容的。

以上是关于一道面试题:静态代码块的执行顺序的主要内容,如果未能解决你的问题,请参考以下文章

Java的静态变量,成员变量,静态代码块,构造块的加载顺序

(转)面试题--JAVA中静态块静态变量加载顺序详解

Java面试题 静态代码块 构造代码块 构造方法 的执行顺序

java面试基础题------》Java 中的父子类静态代码块,代码块,构造方法执行顺序

Java(静态)变量和(静态)代码块的执行顺序

子类继承父类,那么各代码块的执行顺序为: