问题

这也是Java面试中出镜率很高的基础概念问题

  • 描述一下多级继承中字段初始化顺序
  • 描述一下多级继承中类变量初始化顺序
  • 写出运行以下代码时的控制台输出
public class Base {
public static int v1 = method(1);
private static int v2 = method(2); private int v3;
private int v4 = method(3); public Base() {
v3 = method(4);
}
public static int method(int i) {
System.out.println(i);
return i;
}
public static void main(String args[]) {
method(5);
Base b2 = new Base();
}
}

分析

正确回答这些问题, 需要对以下的概念有了解:

  1. static关键字, 静态变量和静态方法
  2. 静态变量和普通成员变量初始化的区别
  3. 类初始化中父类和子类变量的初始化顺序

以下通过具体场景说明

场景一: 单个类的初始化顺序

先看单个类的初始化顺序, 静态和普通变量都根据public和private区分, 交替声明.

Base.java

public class Base {
public static int pub_s = method(1);
private static int pri_s = method(2);
public static int pub_s2 = method(3);
private static int pri_s2 = method(4); private int pri1;
private int pri2 = method(5);
private int pri3;
private int pri4 = method(6); public Base() {
pri1 = method(7);
pri3 = method(8);
}
public static int method(int i) {
System.out.println(i);
return i;
}
public static void main(String args[]) {
method(0);
Base b2 = new Base();
}
}

输出结果为

1
2
3
4
0
5
6
7
8

可以得到以下信息

  1. 静态成员变量初始化最早

    • 与实例初始化无关, 在载入类时完成初始化
    • 初始化顺序与代码顺序一致, 与public还是private无关
  2. 静态成员变量初始化在执行main()函数之前完成, 因为在执行main()函数前, 静态成员初始化就伴随类的载入完成了
  3. 普通成员变量初始化在执行构造函数之前

场景二: 带继承关系的类初始化顺序

保持Base.java不变, 增加Sub.java作为子类

Sub.java

public class Sub extends Base {
public static int sub_pub_s = method(11);
private static int sub_pri_s = method(12);
public static int sub_pub_s2 = method(13);
private static int sub_pri_s2 = method(14); private int sub_pri1;
private int sub_pri2 = method(15);
private int sub_pri3;
private int sub_pri4 = method(16); public Sub() {
sub_pri1 = method(17);
sub_pri3 = method(18);
}
public static void main(String args[]) {
method(10);
Sub b2 = new Sub();
}
}

运行Sub.java, 输出结果为

1
2
3
4
11
12
13
14
10
5
6
7
8
15
16
17
18

可以得到以下信息

  1. 在任何情况下, 静态成员变量都会最先初始化
  2. 在存在继承关系的类中, 父类的静态成员变量先初始化, 然后是子类的静态成员变量
  3. 所有静态成员变量初始化之后, 才开始main函数的执行
  4. 在类实例初始化过程中, 先初始化父类, 再初始化子类, 每一层都是先成员变量, 然后执行构造函数, 所以顺序就是: 父类成员变量, 父类构造函数, 子类成员变量, 最后是子类构造函数

总结

类的构造顺序为

  1. 父类静态成员变量, 其顺序与代码顺序一致, 与public还是private无关
  2. 子类静态成员变量, 其顺序与代码顺序一致, 与public还是private无关
  3. 如果执行类的静态函数(包括main函数), 这个时间点就会开始执行函数
  4. 如果创建了类的实例, 注意这个前提, 下面就会开始普通成员变量的初始化
  5. 父类的普通成员变量
  6. 父类的构造函数
  7. 子类的普通成员变量
  8. 子类的构造函数

Java语法专题2: 类变量的初始化顺序的更多相关文章

  1. Java语法专题1: 类的构造顺序

    合集目录 Java语法专题1: 类的构造顺序 问题 下面的第二个问题来源于Oracle的笔试题, 非常经典的一个问题, 我从07年开始用了十几年. 看似简单, 做对的比例不到2/10. 描述一下多级继 ...

  2. Java类继承关系中的初始化顺序

    Java类初始化的顺序经常让人犯迷糊,现在本文尝试着从JVM的角度,对Java非继承和继承关系中类的初始化顺序进行试验,尝试给出JVM角度的解释. 非继承关系中的初始化顺序 对于非继承关系,主类Ini ...

  3. Java杂谈3——类加载机制与初始化顺序

    Java语言的哲学:一切都是对象.对于Java虚拟机而言,一个普通的Java类同样是一个对象,那如果是对象,必然有它的初始化过程.一个类在JVM中被实例化成一个对象,需要经历三个过程:加载.链接和初始 ...

  4. IT兄弟连 Java语法教程 数组 数组的初始化

    Java语言中数组必须先初始化,然后才可以使用.所谓初始化,就是为数组的数组元素分配内存空间,并为每个数组元素赋初始值. 这时有人会问,能不能只分配内存空间,不赋初始值呢?答案是肯定不行的,一旦为数组 ...

  5. Java中类的数据成员的初始化顺序

    对于单一类: 属性初始化 ---> 按顺序执行静态初始化块(只能操作静态属性) ---> 按顺序执行初始化块 ---> 构造方法 对于存在继承关系的类: 父类属性初始化 ---> ...

  6. java类的加载以及初始化顺序

    类的加载和初始化的了解对于我们对编程的理解有很大帮助,最近在看类的记载方面的问题.从网上查阅了若干文章,现总结如下: 我们通过一段代码来了解类加载和初始化的顺序: package com.classl ...

  7. Java中含有静态成员的的初始化顺序

    class Bowl{ Bowl(int marker){ System.out.println("Bowl(" + marker + ")" ); } voi ...

  8. java对象中继承和变量初始化顺序浅析

    先上例子代码 public class F { int age = 5; public F() { print(); } public void print() { System.out.printl ...

  9. 【深入理解JVM】:Java类继承关系中的初始化顺序

    尝试着仔细阅读thinking in java 看到一篇很好的文章http://blog.csdn.net/u011080472/article/details/51330114

随机推荐

  1. 【LeetCode】89. Gray Code 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  2. CSS实现水平垂直居中的方式有哪些?

    CSS实现水平垂直居中的方式有哪些? 基本结构样式: .box { width: 400px; height: 400px; background-color: red; } .inner { wid ...

  3. MySQL 中常见的时间类型有三种 DATE, DATETIME 和 TIMESTAMP

    MySQL 中常见的时间类型有三种 DATE, DATETIME 和 TIMESTAMP,其中 DATE 类型用于表示日期,但是不会包含时间,格式为 YYYY-MM-DD,而 DATETIME 和 T ...

  4. Normalization Methods

    目录 概 主要内容 Batch Normalization Layer Normalization Instance Normalization Group Normalization Ioffe S ...

  5. Max-Mahalanobis Linear Discriminant Analysis Networks

    目录 概 主要内容 Pang T, Du C, Zhu J, et al. Max-Mahalanobis Linear Discriminant Analysis Networks[C]. inte ...

  6. 美和易思 · 「云农职互联网技术学院」HTML+CSS 做西普尼金表官网

    假期作业,好久没碰了,代码写得很烂......写博客纯属记录! 源代码下载地址:https://download.csdn.net/download/weixin_44893902/12805555 ...

  7. MySQL8.0.20安装详解

    https://blog.csdn.net/yeb112233/article/details/106042867/ alter user root@localhost identified by ' ...

  8. 在动态组件上使用 keep-alive

    ----------------------html.js.style----------------------------------------------- <!DOCTYPE html ...

  9. Java--Map的使用认知

    Java里面的Map是一个抽象接口,有一些类实现的该接口比如HashMap.TreeMap等 HashMap 是一个散列表,存储的内容是靠键值对来映射的(key-value). 基本认识 HashMa ...

  10. Nginx 防爬虫设置

    在conf下  vi 一个文件agent_deny.conf 添加如下内容 #禁止Scrapy|curl等工具的抓取 if ($http_user_agent ~* (Scrapy|Curl|Http ...