Mobile wallpaper 1Mobile wallpaper 2Mobile wallpaper 3Mobile wallpaper 4Mobile wallpaper 5Mobile wallpaper 6Mobile wallpaper 7Mobile wallpaper 8
1060 字
5 分钟
Java:继承的构造和代码块
2026-03-11

目录#

一、子类构造方法#

考虑下面的代码:

public class Base {
int b;
public Base(int b) {
this.b = b;
System.out.println("Base构造方法运行中。");
}
}
public class Derived extends Base{
private int a;
public Derived(int a) {
//需要在第一行加上父类的构造语句,比如:super(1),否则无法运行
//如果参数列表没有b不报错的原因是,子类的构造方法会默认有super(),因此如果参数列表为空编译器会自己构造。
this.a = a;
System.out.println("Derived构造方法运行中。");
}
}
public class Test {
public static void main(String[] args) {
Derived d = new Derived(1);
}
}

尝试运行会发现程序会报错。 这是因为子类在运行构造函数之前要先完成父类的构造,也就是说在Derived的构造方法内部,第一行必须是super的构造方法,比如上面的代码第一行就必须是super(1)

二、代码块执行顺序:#

1.回顾#

现在我们先回顾一下在一个类的初始化中,代码块的执行顺序。

public class TestDemo {
public static String name = "Tim";
public int age;
public double weight;
// 实例代码块1
{
this.age = 18;
this.weight = 60;
System.out.println("实例代码块1运行中");
}
// 静态代码块1
static {
name = "Timi";
System.out.println("静态代码块1运行中");
}
// 构造方法
public TestDemo(int age, double weight) {
System.out.println("构造方法开始执行");
this.age = age;
this.weight = weight;
System.out.println("构造方法结束执行");
}
// 实例代码块2
{
System.out.println("实例代码块2运行中");
}
// 静态代码块2
static {
System.out.println("静态代码块2运行中");
}
public void show() {
//普通代码块
{
System.out.println("普通代码块(局部代码块)运行中");
}
System.out.println("姓名:" + name + " 年龄:" + age + " 体重:" + weight);
}
}

2.继承下的代码块运行顺序#

在这段代码中,类初始化的时候,代码块的执行顺序是:静态代码块 -> 实例代码块 -> 构造函数。 那么在子类和父类的初始化中,代码块的执行顺序是怎么样的呢?

class Person {
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Person:构造方法执行");
}
{
System.out.println("Person:实例代码块执行");
}
static {
System.out.println("Person:静态代码块执行");
}
}
class Student extends Person{
public Student(String name,int age) {
super(name,age);
System.out.println("Student:构造方法执行");
}
{
System.out.println("Student:实例代码块执行");
}
static {
System.out.println("Student:静态代码块执行");
}
}
public class TestDemo {
public static void main(String[] args) {
Student student1 = new Student("张三",19);
System.out.println("===========================");
Student student2 = new Student("李四",20);
}
}

在如上所示的代码中,结果为:

Person:静态代码块执行
Student:静态代码块执行
Person:实例代码块执行
Person:构造方法执行
Student:实例代码块执行
Student:构造方法执行
===========================
Person:实例代码块执行
Person:构造方法执行
Student:实例代码块执行
Student:构造方法执行

在这里代码块的运行顺序是: (父类静态代码块 -> 子类静态代码块) -> 父类的实例和构造 -> 子类的实例和构造。 这样的原因是因为我们知道,静态代码块是在程序加载类的时候就运行了的,并且先有父后有子,因此最早运行的分别是父类和子类的静态代码块。 之后调用构造函数的时候,因为调用子类构造函数的第一步是运行父类的构造函数super,因此,要先运行父类的实例和构造,然后运行子类的实例和构造。 在第二次运行的时候,由于静态代码块只会运行一次,因此只会先后运行父类的实例和构造以及子类的实例和构造。

final关键词#

final关键词修饰成员变量的时候,变量视为常量,不能被修改。 修饰类的时候,类不能被继承。 修饰方法的时候,方法不能被重写。

final class Person {
}
class Student extends Person {//final修饰的类不能被继承
}
public class Test {
public static void main(String[] args) {
final int a = 1;
a = 2;//final修饰的成员变量视为常量,不能被更改。
}
}

下一章讲多态。

Java:继承的构造和代码块
https://blog.csdn.net/2501_93882415/article/details/158851734?spm=1001.2014.3001.5502
作者
Mem0rin
发布于
2026-03-11
许可协议
MIT

部分信息可能已经过时

封面
Sample Song
Sample Artist
封面
Sample Song
Sample Artist
0:00 / 0:00