?♀️前言
一个类是由很多成员所构成,大致分为以下成员。在前面的学习中,我们学习了成员变量和成员方法。今天我们学习类中的另一个成员:代码块
目录
?♀️前言?一、基本介绍?二、代码块分类&作用2.1:静态代码块2.2:构造代码块 ?三:执行顺序再深入
?一、基本介绍
简单来说,代码块就是用花括号{ }
包围起来的一块代码。
语法格式
[修饰符] {代码}
我们看到,就格式而言,代码块和方法(method)有点类似。
代码块vs方法
首先,代码块没有方法名,没有参数列表,没有返回值。这是肉眼可见,与方法不同的点。
其次,在调用上,既然都是数据和操作数据组成的代码,那么都是写来被执行的。对于方法而言,必须要被调用,方法体中的代码才可被执行。那对于静态代码块呢?静态代码块中的代码何时被执行?要弄清楚这个,以及代码块执行的作用,我们先学习代码块的分类,因为不同的代码块有区别,不可一概而论。
?二、代码块分类&作用
首先我们可以根据修饰符的不同,即有无static
修饰。分为以下两种:
Tips:这里我们讨论的代码块,位置都是位于类中的,不去考虑位于方法中的代码块。
2.1:静态代码块
所谓静态代码块,就是被static
所修饰的代码块
eg:
class Person { //实例成员变量 private String name; private int age; private String sex; //静态成员变量 private static int countNum; static { countNum = 0; System.out.println("countNum初始化完毕"); }}
作用:初始化静态成员属性执行时机:随着类的加载而执行 2.2:构造代码块
构造代码块,是指没有被static
修饰的代码块,也叫作实例代码块
eg:
class Person { //实例成员变量 private String name; private int age; private String sex; //静态成员变量 private static int countNum; //静态代码块 static { countNum = 0; System.out.println("countNum初始化完毕"); } //构造代码块 { this.name = "yaoyao"; this.age = 18; this.sex = "female"; }}
作用:初始化实例成员变量执行时机:对象创建后,调用本类构造器前和构造器的关系: public Person(String name, int age, String sex) { //super() //调用本类的构造代码块 //以下是本类构造器的实现 this.name = name; this.age = age; this.sex = sex; }
可以看到,当创建对象时,会调用构造器,但构造器中其实还有隐藏的:super()(即调用父类构造器,进行初始化)
,调用本类构造代码块
,最后再执行本类构造器中的初始化代码。
如果对于代码块的执行顺序,还是不是很清晰,那么下面这一Part,会带你清晰的掌握,什么样的代码块在什么时候执行。
?三:执行顺序再深入
当我们创建一个有继承关系的子类时,内存中,代码执行情况是怎样的呢?
public class A { static { System.out.println("A类静态代码块被执行"); } { System.out.println("A类构造代码块被执行"); } public A() { //super(); //调用A类普通代码块 System.out.println("A类构造方法被调用"); }}
public class B extends A{ static { System.out.println("B类静态代码块被执行"); } { System.out.println("B类构造代码块被执行"); } public B() { //super(); //调用A类普通代码块 System.out.println("B类构造方法被调用"); }}
public class C extends B{ static { System.out.println("C类静态代码块被执行"); } { System.out.println("C类构造代码块被执行"); } public C() { //super(); //调用A类普通代码块 System.out.println("C类构造方法被调用"); }}
以下是测试类,用来测试子类C被创建时,代码块、构造方法执行顺序
public class Test { public static void main(String[] args) { C c = new C(); //A类静态代码块被执行 //B类静态代码块被执行 //C类静态代码块被执行 //A类构造代码块被执行 //A类构造方法被调用 //B类构造代码块被执行 //B的构造方法被调用 //C类构造代码块被执行 //C类构造方法被调用 }}
总结
继承查找关系,从顶级父类开始,从上往下逐级加载 父类静态代码块执行子类静态代码块执行 调用子类构造器 执行子类构造器方法体之前隐含的super()(初始化父类,调用父类构造器)执行子类构造代码块执行子类构造器方法体LeetCode每日一题–进击大厂算法