java父类和子类初始化顺序的深入理解

yizhihongxing

下面我将详细讲解Java父类和子类初始化顺序的深入理解。

父类和子类初始化顺序的基本概念

在Java中,对象的初始化包括两部分:静态初始化和实例初始化。当类被加载时,它的静态成员会被初始化;当类的对象被创建时,会调用构造函数进行实例初始化。父类和子类的初始化顺序如下:

  1. 父类的静态成员初始化
  2. 子类的静态成员初始化
  3. 父类的实例成员初始化
  4. 父类的构造函数初始化
  5. 子类的实例成员初始化
  6. 子类的构造函数初始化

示例说明一

我们考虑下面的代码:

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 class Test {
    public static void main(String[] args) {
        new B();
    }
}

输出:

A的静态代码块
B的静态代码块
A的实例代码块
A的构造函数
B的实例代码块
B的构造函数

这样的输出结果是符合我们上面说的初始化顺序的。你可以看到,在对象实例化前,父类的静态变量会被初始化,然后是子类的静态变量初始化。接下来,父类的实例成员变量初始化,执行父类的构造函数;然后是子类的实例成员变量初始化和子类的构造函数。

示例说明二

下面再来一个例子,考虑子类是继承了父类的构造函数:

class A {
    public A() {
        System.out.println("A的构造函数");
        method();
    }

    public void method() {
        System.out.println("A的method方法");
    }
}

class B extends A {
    private int a = 1;

    public void method() {
        System.out.println("B的method方法,a = " + a);
    }

    public B() {
        System.out.println("B的构造函数");
    }
}

public class Test {
    public static void main(String[] args) {
        new B();
    }
}

输出:

A的构造函数
B的method方法,a = 0
B的构造函数

在这个例子中,我们可以看到,虽然在父类的构造函数中调用了method方法,但是由于这个方法被子类override了,在父类构造函数调用时,实际上是调用了子类的方法。由于子类的成员变量还没有被初始化,所以a的值为0。

这里提醒一下,最好不要在父类构造函数中调用被子类override的方法,否则可能会出现一些奇怪的结果,因为子类的成员变量还没有被初始化。这就是父类和子类初始化顺序的一个比较容易出错的地方。

以上是关于Java父类和子类初始化顺序的深入理解,以及两个实例讲解。希望能对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java父类和子类初始化顺序的深入理解 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • vue2.0 实现富文本编辑器功能

    Vue2.0 实现富文本编辑器功能 介绍 在Vue2.0中要实现富文本编辑器功能,可以选择使用第三方富文本编辑器插件,或者自己编写实现。本文将介绍一种使用Vue2.0自定义组件实现富文本编辑器的方法。 准备工作 在开始之前,需要保证已经安装了Vue2.0和相关的vue-loader、vue-template-compiler的依赖。可以通过npm安装: np…

    other 2023年6月26日
    00
  • vue利用vue-animate-number插件动态展示数字

    Vue利用vue-animate-number插件动态展示数字 在Vue项目中,有时需要动态展示数字,例如倒计时、计数器等。vue-animate-number是一个Vue插件可以帮助我们实现数字的动态展示。本攻略将详细介绍如何使用vue-animate插件动态展示数字,并提供两个示例说明。 解决方法 以下是使用vue-animate-number插件动态展…

    other 2023年5月7日
    00
  • pytest用例间参数传递的两种实现方式示例

    Pytest用例间参数传递的两种实现方式示例 在Pytest中,有两种常见的方式可以在测试用例之间传递参数。下面将详细介绍这两种方式,并提供示例说明。 1. 使用pytest.fixture装饰器 pytest.fixture装饰器可以用于创建可重用的测试用例参数。通过将参数定义为fixture,可以在多个测试用例中共享这些参数。 示例说明: import …

    other 2023年7月29日
    00
  • python图形开发GUI库pyqt5的详细使用方法及各控件的属性与方法

    下面我将为您详细讲解“Python图形开发GUI库PyQt5的详细使用方法及各控件的属性与方法”的完整攻略。 Pyqt5概述 PyQt5是一个Python包,包含了用于创建图形用户界面(GUI)的工具和相关组件。它是Qt应用程序框架的Python绑定,允许Python程序员使用Qt的API。 PyQt5模块分为两类:QtCore和QtWidgets。- Qt…

    other 2023年6月27日
    00
  • 使用Maven将springboot工程打包成docker镜像

    下面给出使用Maven将Spring Boot工程打包成Docker镜像的完整攻略,过程中包含两个示例说明。 环境准备 安装Docker,官网下载并安装Docker。 在本地Maven配置文件(settings.xml)中添加Docker镜像仓库的认证信息,以便Maven在上传Docker镜像时进行认证。如果还没有该文件,请复制$MAVEN_HOME/con…

    other 2023年6月27日
    00
  • 电脑文件名后缀不见了怎么回事?如何解决?

    电脑文件名后缀不见了可能是因为系统设置问题、病毒感染或人为操作等原因引起,一般可以通过以下方法进行解决。 方法一:调整系统显示设置 有时候可能是操作系统的默认设置让文件名后缀被隐藏了,可以通过调整系统显示设置来解决。 右键点击桌面空白处,选择“个性化”; 点击“更改桌面图标和视图”; 在“视图”标签下,找到“隐藏已知文件类型的扩展名”选项,将勾选去掉; 保存…

    other 2023年6月26日
    00
  • c#键值对的类型

    C#键值对的类型 在C#语言中,键值对是常见的数据类型之一。键值对存储了一组键值(key-value)对,每个键值对中都有一个键和对应的值。在实际应用中,我们可以使用键值对来存储和获取数据。 Dictionary类型 C#中最常用的键值对类型是Dictionary。它是一个泛型类型,可以定义键和值的类型。例如,以下代码定义了一个字符串为键、整数为值的Dict…

    其他 2023年3月28日
    00
  • 微信小程序button组件使用详解

    以下是“微信小程序button组件使用详解”的完整攻略: 1. button组件概述 button组件是微信小程序中常用的组件之一,用于创建按钮。button组件可以设置按钮的文本、样式、大小、事件等属性,可以实现多种不同的按钮效果。 2. button组件的使用 2.1 基本用法 button组件的基本用法非常简单,只需要在wxml文件中添加button标…

    other 2023年5月8日
    00
合作推广
合作推广
分享本页
返回顶部