1、代码块
使用 {} 定义的一段代码称为代码块,代码块又可以分为四种:
- 普通代码块
- 构造代码块
- 静态代码块
- 同步代码块
2、普通代码块
普通代码块:定义在方法中的代码块。
public static void main(String[] args) {
// 普通代码块
{
int x = 10;
System.out.println(x);
}
int x = 100;
System.out.println(x);
}
3、构造代码块
构造代码块:又称为实例代码块,是定义在类中的代码块,一般用来初始化实例成员变量。
- 一个类中可以有多个实例代码块。
- 实例代码块在每次创建对象时执行,目的是将对象中的成员初始化完整。
- 创建对象时,实例代码块按照出现的先后次序执行。
- 实例代码块中的内容在编译时会按照其在类中的先后次序被拷贝到构造方法中,且被拷贝到第一条语句之前(注意构造方法中如果有 super(…) 语句,就在其后)。
public class Dog {
private String name;
private String gender;
private int age;
private String color;
{
name = "狗狗";
gender = "公";
}
{
age = 1;
color = "金黄色";
}
public Dog(){
System.out.println("Dog()");
}
public void print(){
System.out.println(name + " " + gender + " " + age + " " + color);
}
public static void main(String[] args) {
Dog dog = new Dog();
dog.print();
}
}
运行结果:
4、静态代码块
静态代码块:使用 static 定义的代码块,一般用于初始化静态成员变量。
// 静态代码块
static {
classRoom = "room306";
}
- 无论创建多少个对象,静态代码块只执行一次,在类加载阶段执行。
- 如果一个类中有多个静态代码块,则在编译代码时,按照定义的先后次序依次执行。
- 编译器编译后,会将静态代码块按照先后次序放在 < clinit > 方法中。
5、代码块的执行顺序
- 静态代码块只执行一次,在类加载阶段执行。
- 构造代码块在每次创建对象时都会执行,编译器在编译时,会将构造代码块的内容拷贝到构造方法的第一条语句之前,因此先执行构造代码块,再执行构造方法中的内容。
- 由于静态代码块在类加载阶段执行,而创建对象后才会执行构造代码块,因此静态代码块比构造代码块先执行。
- 当有继承关系时,由于先加载父类,后加载子类,因此父类的静态代码块优于子类的静态代码块;由于调用父类的构造方法语句是子类的构造方法中的第一条语句,因此父类的构造代码块优于子类的构造代码块,父类的构造方法由于子类的构造方法。
// 父类
public class Person {
public String name;
public String gender;
public int age;
public Person(String name, String gender, int age) {
this.name = name;
this.gender = gender;
this.age = age;
System.out.println("基类的构造方法~~~");
}
{
System.out.println("基类中的实例代码块~~~");
}
static{
System.out.println("基类中的静态代码块");
}
}
// 子类
public class Student extends Person {
public int stuId;
public Student(String name, String gender, int age, int stuId) {
// 调用父类的构造方法
super(name, gender, age);
this.stuId = stuId;
System.out.println("子类构造方法~~~");
}
{
System.out.println("子类中的实例代码块~~~");
}
static {
System.out.println("子类中的静态代码块~~~");
}
public static void main(String[] args) {
// 创建多个对象
Student s1 = new Student("张三","男", 18,20220901);
System.out.println("====================");
Student s2 = new Student("张三","男", 18,20220901);
}
}
运行结果: