Marvel-Site Marvel-Site
首页
  • Java

    • Java基础
    • Java进阶
    • Java容器
    • Java并发编程
    • Java虚拟机
  • 计算机基础

    • 数据结构与算法
    • 计算机网络
    • 操作系统
    • Linux
  • 框架|中间件

    • Spring
    • MySQL
    • Redis
    • MQ
    • Zookeeper
    • Git
  • 架构

    • 分布式
    • 高并发
    • 高可用
    • 架构
  • 框架

    • React
    • 其他
  • 实用工具
  • 安装配置

    • Linux
    • Windows
    • Mac
  • 开发工具

    • IDEA
    • VsCode
  • 关于
  • 收藏
  • 草稿
  • 索引

    • 分类
    • 标签
    • 归档
GitHub (opens new window)

Marvel

吾必当乘此羽葆盖车
首页
  • Java

    • Java基础
    • Java进阶
    • Java容器
    • Java并发编程
    • Java虚拟机
  • 计算机基础

    • 数据结构与算法
    • 计算机网络
    • 操作系统
    • Linux
  • 框架|中间件

    • Spring
    • MySQL
    • Redis
    • MQ
    • Zookeeper
    • Git
  • 架构

    • 分布式
    • 高并发
    • 高可用
    • 架构
  • 框架

    • React
    • 其他
  • 实用工具
  • 安装配置

    • Linux
    • Windows
    • Mac
  • 开发工具

    • IDEA
    • VsCode
  • 关于
  • 收藏
  • 草稿
  • 索引

    • 分类
    • 标签
    • 归档
GitHub (opens new window)
  • Java

    • Java基础

    • Java进阶

      • 类的初始化与对象的初始化
        • 代码
        • 涉及知识点
        • 分析过程
      • Object类
      • 深度理解字符串String
      • Integer创建对象分析
      • 从原理上分析 i = i++ 与 i = ++i
      • Comparable和Comparator的区别
      • 四种引用介绍
      • 静态代理与动态代理
      • 位运算
    • Java容器

    • Java并发编程

    • Java虚拟机

    • 常见面试题

  • 计算机基础

  • 框架|中间件

  • 架构

  • 后端
  • Java
  • Java进阶
Marvel
2022-09-05
目录

类的初始化与对象的初始化

# 类的初始化与对象的初始化

# 代码

下面两段代码,分析他们输出的情况:

父类:Father

public class Father {
    private int i =  method1();
    private static int j = method2();

    static {
        System.out.print("(1)");
    }

    Father() {
        System.out.print("(2)");
    }
    {
        System.out.print("(3)");
    }
    public int method1() {
        System.out.print("(4)");
        return 1;
    }
    public static int method2() {
        System.out.print("(5)");
        return 1;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

子类:Son

public class Son extends Father {

    private int i =  method1();
    private static int j = method2();

    static {
        System.out.print("(6)");
    }

    Son() {
        System.out.print("(7)");
    }
    {
        System.out.print("(8)");
    }
    public int method1() {
        System.out.print("(9)");
        return 1;
    }
    public static int method2() {
        System.out.print("(10)");
        return 1;
    }

    public static void main(String[] args) {
        Son son1 = new Son();
        System.out.println();
        Son son2 = new Son();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

输出:

(5)(1)(10)(6)(9)(3)(2)(9)(8)(7)
(9)(3)(2)(9)(8)(7)
1
2

# 涉及知识点

  • 类的初始化过程
    • 一个类要创建实例需要先加载并初始化该类
      • main 方法所在的类需要先加载和初始化
    • 一个子类要初始化需要先初始化父类
    • 一个类初始化就是执行 <client>() 方法
      • <client>() 方法由静态类变量显示赋值代码和静态代码块组成
      • 类变量显式赋值代码和静态代码块代码从上到下顺序执行
      • <client>() 方法只执行一次
  • 实例初始化过程
    • 实例初始化就是执行 <int>() 方法
      • <int>() 方法可能重载多个,由几个构造器就有几个 <int>() 方法
      • <int>() 方法由非静态实例变量显示赋值代码和非静态代码块、对应构造器代码组成
      • 非静态实例变量显示赋值代码和非静态代码块从上到下顺序执行,而对应构造器的 代码最后执行
      • 每次创建实例对象,调用对应构造器,执行的就是对应的 <int>() 方法
      • <int>() 方法的首行是 super() 或 super(参数列表),即对应父类的 <int>() 方法,在子类的构造器中一定会调用父类的构造器。
  • 方法重写
    • 不可以被重写的方法:fianal、静态方法、private等子类不可见的方法
    • 对象多态
      • 子类如果重写父类的方法,通过子类调用的一定是子类重写过的代码
      • 非静态方法默认的调用对象是 this
      • this 对象在构造器或者说 <int> 方法中就是正在创建的对象

# 分析过程

首先执行类的初始化,先父类再再子类,类变量显式赋值代码和静态代码块代码从上到下顺序执行。所以输出

(5)(1)(10)(6)
1

下面是实例的初始化,先执行 super(),再非静态实例变量显示赋值代码和非静态代码块从上到下顺序执行,最后执行对应构造器。

<init>()首行调用 super(),执行父类的

  • 先执行 i = test(),该方法被重写此时 this.test() 调用的是子类的 test() 方法,输出 (9)
  • 非静态代码块,输出 (3)
  • 构造器,输出 (2)

在按照顺序执行子类的

  • 先执行 i = test(),输出 (9)
  • 非静态代码块,输出 (8)
  • 构造器,输出 (7)

所以第一次创建对象的时候输出

(9)(3)(2)(9)(8)(7)
1

同时,每一次创建实例,都会输出相同的内容,但是类的初始化只会执行一次。

编辑 (opens new window)
上次更新: 2024/04/17, 21:30:18
Java函数式编程
Object类

← Java函数式编程 Object类→

最近更新
01
位运算
05-21
02
二叉树
05-12
03
Spring三级缓存解决循环依赖
03-25
更多文章>
Theme by Vdoing | Copyright © 2022-2024 Marvel
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式